channels/smartcard: add rgSCardContextList
This commit is contained in:
parent
22e2490df7
commit
62395f7b0c
@ -37,32 +37,6 @@
|
|||||||
|
|
||||||
static BOOL g_SmartCardAsync = TRUE;
|
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)
|
static void smartcard_free(DEVICE* device)
|
||||||
{
|
{
|
||||||
SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) device;
|
SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) device;
|
||||||
@ -75,7 +49,8 @@ static void smartcard_free(DEVICE* device)
|
|||||||
Stream_Free(smartcard->device.data, TRUE);
|
Stream_Free(smartcard->device.data, TRUE);
|
||||||
|
|
||||||
MessageQueue_Free(smartcard->IrpQueue);
|
MessageQueue_Free(smartcard->IrpQueue);
|
||||||
ListDictionary_Free(smartcard->OutstandingIrps);
|
ListDictionary_Free(smartcard->rgSCardContextList);
|
||||||
|
ListDictionary_Free(smartcard->rgOutstandingMessages);
|
||||||
|
|
||||||
free(device);
|
free(device);
|
||||||
}
|
}
|
||||||
@ -91,16 +66,18 @@ static void smartcard_init(DEVICE* device)
|
|||||||
int index;
|
int index;
|
||||||
int keyCount;
|
int keyCount;
|
||||||
ULONG_PTR* pKeys;
|
ULONG_PTR* pKeys;
|
||||||
|
SCARDCONTEXT hContext;
|
||||||
|
|
||||||
SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) device;
|
SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) device;
|
||||||
|
|
||||||
if (ListDictionary_Count(smartcard->OutstandingIrps) > 0)
|
if (ListDictionary_Count(smartcard->rgOutstandingMessages) > 0)
|
||||||
{
|
{
|
||||||
pKeys = NULL;
|
pKeys = NULL;
|
||||||
keyCount = ListDictionary_GetKeys(smartcard->OutstandingIrps, &pKeys);
|
keyCount = ListDictionary_GetKeys(smartcard->rgOutstandingMessages, &pKeys);
|
||||||
|
|
||||||
for (index = 0; index < keyCount; index++)
|
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)
|
if (irp)
|
||||||
irp->cancelled = TRUE;
|
irp->cancelled = TRUE;
|
||||||
@ -108,6 +85,28 @@ static void smartcard_init(DEVICE* device)
|
|||||||
|
|
||||||
free(pKeys);
|
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)
|
void smartcard_complete_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
|
||||||
@ -115,7 +114,7 @@ void smartcard_complete_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
|
|||||||
void* key;
|
void* key;
|
||||||
|
|
||||||
key = (void*) (size_t) irp->CompletionId;
|
key = (void*) (size_t) irp->CompletionId;
|
||||||
ListDictionary_Remove(smartcard->OutstandingIrps, key);
|
ListDictionary_Remove(smartcard->rgOutstandingMessages, key);
|
||||||
|
|
||||||
if (!irp->cancelled)
|
if (!irp->cancelled)
|
||||||
irp->Complete(irp);
|
irp->Complete(irp);
|
||||||
@ -147,7 +146,7 @@ void smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
|
|||||||
UINT32 ioControlCode = 0;
|
UINT32 ioControlCode = 0;
|
||||||
|
|
||||||
key = (void*) (size_t) irp->CompletionId;
|
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)
|
if (irp->MajorFunction == IRP_MJ_DEVICE_CONTROL)
|
||||||
{
|
{
|
||||||
@ -249,8 +248,6 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
|
|||||||
name = device->Name;
|
name = device->Name;
|
||||||
path = device->Path;
|
path = device->Path;
|
||||||
|
|
||||||
smartcard_environment_init();
|
|
||||||
|
|
||||||
smartcard = (SMARTCARD_DEVICE*) calloc(1, sizeof(SMARTCARD_DEVICE));
|
smartcard = (SMARTCARD_DEVICE*) calloc(1, sizeof(SMARTCARD_DEVICE));
|
||||||
|
|
||||||
if (!smartcard)
|
if (!smartcard)
|
||||||
@ -288,7 +285,8 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
|
|||||||
WLog_SetLogLevel(smartcard->log, WLOG_DEBUG);
|
WLog_SetLogLevel(smartcard->log, WLOG_DEBUG);
|
||||||
|
|
||||||
smartcard->IrpQueue = MessageQueue_New(NULL);
|
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->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) smartcard_thread_func,
|
||||||
smartcard, CREATE_SUSPENDED, NULL);
|
smartcard, CREATE_SUSPENDED, NULL);
|
||||||
|
@ -92,7 +92,8 @@ struct _SMARTCARD_DEVICE
|
|||||||
|
|
||||||
HANDLE thread;
|
HANDLE thread;
|
||||||
wMessageQueue* IrpQueue;
|
wMessageQueue* IrpQueue;
|
||||||
wListDictionary* OutstandingIrps;
|
wListDictionary* rgSCardContextList;
|
||||||
|
wListDictionary* rgOutstandingMessages;
|
||||||
};
|
};
|
||||||
typedef struct _SMARTCARD_DEVICE SMARTCARD_DEVICE;
|
typedef struct _SMARTCARD_DEVICE SMARTCARD_DEVICE;
|
||||||
|
|
||||||
|
@ -150,7 +150,7 @@ static UINT32 smartcard_EstablishContext(SMARTCARD_DEVICE* smartcard, IRP* irp)
|
|||||||
UINT32 status;
|
UINT32 status;
|
||||||
SCARDCONTEXT hContext = -1;
|
SCARDCONTEXT hContext = -1;
|
||||||
EstablishContext_Call call;
|
EstablishContext_Call call;
|
||||||
EstablishContext_Return ret;
|
EstablishContext_Return ret = { 0 };
|
||||||
|
|
||||||
status = smartcard_unpack_establish_context_call(smartcard, irp->input, &call);
|
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);
|
status = ret.ReturnCode = SCardEstablishContext(call.dwScope, NULL, NULL, &hContext);
|
||||||
|
|
||||||
if (status)
|
if (ret.ReturnCode == SCARD_S_SUCCESS)
|
||||||
return status;
|
{
|
||||||
|
void* key = (void*) (size_t) hContext;
|
||||||
|
ListDictionary_Add(smartcard->rgSCardContextList, key, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
smartcard_scard_context_native_to_redir(smartcard, &(ret.hContext), hContext);
|
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);
|
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");
|
smartcard_trace_long_return(smartcard, &ret, "ReleaseContext");
|
||||||
|
|
||||||
return ret.ReturnCode;
|
return ret.ReturnCode;
|
||||||
|
Loading…
Reference in New Issue
Block a user