channels/smartcard: add rgSCardContextList

This commit is contained in:
Marc-André Moreau 2014-05-06 17:42:10 -04:00
parent 22e2490df7
commit 62395f7b0c
3 changed files with 47 additions and 39 deletions

View File

@ -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);

View File

@ -92,7 +92,8 @@ struct _SMARTCARD_DEVICE
HANDLE thread;
wMessageQueue* IrpQueue;
wListDictionary* OutstandingIrps;
wListDictionary* rgSCardContextList;
wListDictionary* rgOutstandingMessages;
};
typedef struct _SMARTCARD_DEVICE SMARTCARD_DEVICE;

View File

@ -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;