From 62395f7b0c2db9ac48f66a6ba4704fe0299ec688 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Tue, 6 May 2014 17:42:10 -0400 Subject: [PATCH] channels/smartcard: add rgSCardContextList --- channels/smartcard/client/smartcard_main.c | 68 +++++++++---------- channels/smartcard/client/smartcard_main.h | 3 +- .../smartcard/client/smartcard_operations.c | 15 +++- 3 files changed, 47 insertions(+), 39 deletions(-) diff --git a/channels/smartcard/client/smartcard_main.c b/channels/smartcard/client/smartcard_main.c index 5a694b4a3..da7e67fbb 100644 --- a/channels/smartcard/client/smartcard_main.c +++ b/channels/smartcard/client/smartcard_main.c @@ -37,32 +37,6 @@ static BOOL g_SmartCardAsync = TRUE; -int smartcard_environment_init() -{ - DWORD nSize; - char* envSmartCardAsync; - - nSize = GetEnvironmentVariableA("FREERDP_SMARTCARD_ASYNC", NULL, 0); - - if (nSize) - { - envSmartCardAsync = (LPSTR) malloc(nSize); - nSize = GetEnvironmentVariableA("FREERDP_SMARTCARD_ASYNC", envSmartCardAsync, nSize); - - if (envSmartCardAsync) - { - if (_stricmp(envSmartCardAsync, "0") == 0) - g_SmartCardAsync = FALSE; - else - g_SmartCardAsync = TRUE; - - free(envSmartCardAsync); - } - } - - return 0; -} - static void smartcard_free(DEVICE* device) { SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) device; @@ -75,7 +49,8 @@ static void smartcard_free(DEVICE* device) Stream_Free(smartcard->device.data, TRUE); MessageQueue_Free(smartcard->IrpQueue); - ListDictionary_Free(smartcard->OutstandingIrps); + ListDictionary_Free(smartcard->rgSCardContextList); + ListDictionary_Free(smartcard->rgOutstandingMessages); free(device); } @@ -91,16 +66,18 @@ static void smartcard_init(DEVICE* device) int index; int keyCount; ULONG_PTR* pKeys; + SCARDCONTEXT hContext; + SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) device; - if (ListDictionary_Count(smartcard->OutstandingIrps) > 0) + if (ListDictionary_Count(smartcard->rgOutstandingMessages) > 0) { pKeys = NULL; - keyCount = ListDictionary_GetKeys(smartcard->OutstandingIrps, &pKeys); + keyCount = ListDictionary_GetKeys(smartcard->rgOutstandingMessages, &pKeys); for (index = 0; index < keyCount; index++) { - irp = (IRP*) ListDictionary_GetItemValue(smartcard->OutstandingIrps, (void*) pKeys[index]); + irp = (IRP*) ListDictionary_GetItemValue(smartcard->rgOutstandingMessages, (void*) pKeys[index]); if (irp) irp->cancelled = TRUE; @@ -108,6 +85,28 @@ static void smartcard_init(DEVICE* device) free(pKeys); } + + /** + * On protocol termination, the following actions are performed: + * For each context in rgSCardContextList, SCardCancel is called causing all outstanding messages to be processed. + * After there are no more outstanding messages, SCardReleaseContext is called on each context and the context MUST + * be removed from rgSCardContextList. + */ + + if (ListDictionary_Count(smartcard->rgSCardContextList) > 0) + { + pKeys = NULL; + keyCount = ListDictionary_GetKeys(smartcard->rgSCardContextList, &pKeys); + + for (index = 0; index < keyCount; index++) + { + hContext = (SCARDCONTEXT) ListDictionary_GetItemValue(smartcard->rgSCardContextList, (void*) pKeys[index]); + + SCardCancel(hContext); + } + + free(pKeys); + } } void smartcard_complete_irp(SMARTCARD_DEVICE* smartcard, IRP* irp) @@ -115,7 +114,7 @@ void smartcard_complete_irp(SMARTCARD_DEVICE* smartcard, IRP* irp) void* key; key = (void*) (size_t) irp->CompletionId; - ListDictionary_Remove(smartcard->OutstandingIrps, key); + ListDictionary_Remove(smartcard->rgOutstandingMessages, key); if (!irp->cancelled) irp->Complete(irp); @@ -147,7 +146,7 @@ void smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp) UINT32 ioControlCode = 0; key = (void*) (size_t) irp->CompletionId; - ListDictionary_Add(smartcard->OutstandingIrps, key, irp); + ListDictionary_Add(smartcard->rgOutstandingMessages, key, irp); if (irp->MajorFunction == IRP_MJ_DEVICE_CONTROL) { @@ -249,8 +248,6 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) name = device->Name; path = device->Path; - smartcard_environment_init(); - smartcard = (SMARTCARD_DEVICE*) calloc(1, sizeof(SMARTCARD_DEVICE)); if (!smartcard) @@ -288,7 +285,8 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) WLog_SetLogLevel(smartcard->log, WLOG_DEBUG); smartcard->IrpQueue = MessageQueue_New(NULL); - smartcard->OutstandingIrps = ListDictionary_New(TRUE); + smartcard->rgSCardContextList = ListDictionary_New(TRUE); + smartcard->rgOutstandingMessages = ListDictionary_New(TRUE); smartcard->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) smartcard_thread_func, smartcard, CREATE_SUSPENDED, NULL); diff --git a/channels/smartcard/client/smartcard_main.h b/channels/smartcard/client/smartcard_main.h index c3661bc6c..54bae24ec 100644 --- a/channels/smartcard/client/smartcard_main.h +++ b/channels/smartcard/client/smartcard_main.h @@ -92,7 +92,8 @@ struct _SMARTCARD_DEVICE HANDLE thread; wMessageQueue* IrpQueue; - wListDictionary* OutstandingIrps; + wListDictionary* rgSCardContextList; + wListDictionary* rgOutstandingMessages; }; typedef struct _SMARTCARD_DEVICE SMARTCARD_DEVICE; diff --git a/channels/smartcard/client/smartcard_operations.c b/channels/smartcard/client/smartcard_operations.c index 17ec2566b..b7e5c4b64 100644 --- a/channels/smartcard/client/smartcard_operations.c +++ b/channels/smartcard/client/smartcard_operations.c @@ -150,7 +150,7 @@ static UINT32 smartcard_EstablishContext(SMARTCARD_DEVICE* smartcard, IRP* irp) UINT32 status; SCARDCONTEXT hContext = -1; EstablishContext_Call call; - EstablishContext_Return ret; + EstablishContext_Return ret = { 0 }; status = smartcard_unpack_establish_context_call(smartcard, irp->input, &call); @@ -161,8 +161,11 @@ static UINT32 smartcard_EstablishContext(SMARTCARD_DEVICE* smartcard, IRP* irp) status = ret.ReturnCode = SCardEstablishContext(call.dwScope, NULL, NULL, &hContext); - if (status) - return status; + if (ret.ReturnCode == SCARD_S_SUCCESS) + { + void* key = (void*) (size_t) hContext; + ListDictionary_Add(smartcard->rgSCardContextList, key, NULL); + } smartcard_scard_context_native_to_redir(smartcard, &(ret.hContext), hContext); @@ -194,6 +197,12 @@ static UINT32 smartcard_ReleaseContext(SMARTCARD_DEVICE* smartcard, IRP* irp) status = ret.ReturnCode = SCardReleaseContext(hContext); + if (ret.ReturnCode == SCARD_S_SUCCESS) + { + void* key = (void*) (size_t) hContext; + ListDictionary_Remove(smartcard->rgSCardContextList, key); + } + smartcard_trace_long_return(smartcard, &ret, "ReleaseContext"); return ret.ReturnCode;