channels/smartcard: create smartcard context data structures with associated thread
This commit is contained in:
parent
2da6111972
commit
fc39f6bc8d
@ -35,6 +35,79 @@
|
||||
|
||||
#include "smartcard_main.h"
|
||||
|
||||
void* smartcard_context_thread(SMARTCARD_CONTEXT* pContext)
|
||||
{
|
||||
IRP* irp;
|
||||
DWORD nCount;
|
||||
DWORD status;
|
||||
HANDLE hEvents[2];
|
||||
wMessage message;
|
||||
SMARTCARD_DEVICE* smartcard;
|
||||
|
||||
smartcard = pContext->smartcard;
|
||||
|
||||
nCount = 0;
|
||||
hEvents[nCount++] = MessageQueue_Event(pContext->IrpQueue);
|
||||
|
||||
while (1)
|
||||
{
|
||||
status = WaitForMultipleObjects(nCount, hEvents, FALSE, INFINITE);
|
||||
|
||||
if (WaitForSingleObject(MessageQueue_Event(pContext->IrpQueue), 0) == WAIT_OBJECT_0)
|
||||
{
|
||||
if (!MessageQueue_Peek(pContext->IrpQueue, &message, TRUE))
|
||||
break;
|
||||
|
||||
if (message.id == WMQ_QUIT)
|
||||
break;
|
||||
|
||||
irp = (IRP*) message.wParam;
|
||||
|
||||
if (irp)
|
||||
{
|
||||
smartcard_process_irp(smartcard, irp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ExitThread(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SMARTCARD_CONTEXT* smartcard_context_new(SMARTCARD_DEVICE* smartcard, SCARDCONTEXT hContext)
|
||||
{
|
||||
SMARTCARD_CONTEXT* pContext;
|
||||
|
||||
pContext = (SMARTCARD_CONTEXT*) calloc(1, sizeof(SMARTCARD_CONTEXT));
|
||||
|
||||
if (!pContext)
|
||||
return pContext;
|
||||
|
||||
pContext->hContext = hContext;
|
||||
|
||||
pContext->IrpQueue = MessageQueue_New(NULL);
|
||||
|
||||
pContext->thread = CreateThread(NULL, 0,
|
||||
(LPTHREAD_START_ROUTINE) smartcard_context_thread,
|
||||
pContext, 0, NULL);
|
||||
|
||||
return pContext;
|
||||
}
|
||||
|
||||
void smartcard_context_free(SMARTCARD_CONTEXT* pContext)
|
||||
{
|
||||
if (!pContext)
|
||||
return;
|
||||
|
||||
MessageQueue_PostQuit(pContext->IrpQueue, 0);
|
||||
WaitForSingleObject(pContext->thread, INFINITE);
|
||||
CloseHandle(pContext->thread);
|
||||
|
||||
MessageQueue_Free(pContext->IrpQueue);
|
||||
|
||||
free(pContext);
|
||||
}
|
||||
|
||||
static void smartcard_free(DEVICE* device)
|
||||
{
|
||||
SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) device;
|
||||
@ -71,7 +144,7 @@ static void smartcard_init(DEVICE* device)
|
||||
int keyCount;
|
||||
ULONG_PTR* pKeys;
|
||||
SCARDCONTEXT hContext;
|
||||
|
||||
SMARTCARD_CONTEXT* pContext;
|
||||
SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) device;
|
||||
|
||||
/**
|
||||
@ -92,10 +165,16 @@ static void smartcard_init(DEVICE* device)
|
||||
|
||||
for (index = 0; index < keyCount; index++)
|
||||
{
|
||||
hContext = (SCARDCONTEXT) ListDictionary_GetItemValue(smartcard->rgSCardContextList, (void*) pKeys[index]);
|
||||
pContext = (SMARTCARD_CONTEXT*) ListDictionary_GetItemValue(smartcard->rgSCardContextList, (void*) pKeys[index]);
|
||||
|
||||
if (!pContext)
|
||||
continue;
|
||||
|
||||
hContext = pContext->hContext;
|
||||
|
||||
if (SCardIsValidContext(hContext))
|
||||
{
|
||||
printf("SCardCancel: 0x%08X\n", hContext);
|
||||
SCardCancel(hContext);
|
||||
}
|
||||
}
|
||||
@ -114,12 +193,16 @@ static void smartcard_init(DEVICE* device)
|
||||
|
||||
for (index = 0; index < keyCount; index++)
|
||||
{
|
||||
hContext = (SCARDCONTEXT) ListDictionary_GetItemValue(smartcard->rgSCardContextList, (void*) pKeys[index]);
|
||||
pContext = (SMARTCARD_CONTEXT*) ListDictionary_Remove(smartcard->rgSCardContextList, (void*) pKeys[index]);
|
||||
|
||||
ListDictionary_Remove(smartcard->rgSCardContextList, (void*) pKeys[index]);
|
||||
if (!pContext)
|
||||
continue;
|
||||
|
||||
hContext = pContext->hContext;
|
||||
|
||||
if (SCardIsValidContext(hContext))
|
||||
{
|
||||
printf("SCardReleaseContext: 0x%08X\n", hContext);
|
||||
SCardReleaseContext(hContext);
|
||||
}
|
||||
}
|
||||
|
@ -81,6 +81,17 @@
|
||||
#define SCARD_IOCTL_GETREADERICON RDP_SCARD_CTL_CODE(67) /* SCardGetReaderIconA */
|
||||
#define SCARD_IOCTL_GETDEVICETYPEID RDP_SCARD_CTL_CODE(68) /* SCardGetDeviceTypeIdA */
|
||||
|
||||
typedef struct _SMARTCARD_DEVICE SMARTCARD_DEVICE;
|
||||
|
||||
struct _SMARTCARD_CONTEXT
|
||||
{
|
||||
HANDLE thread;
|
||||
SCARDCONTEXT hContext;
|
||||
wMessageQueue* IrpQueue;
|
||||
SMARTCARD_DEVICE* smartcard;
|
||||
};
|
||||
typedef struct _SMARTCARD_CONTEXT SMARTCARD_CONTEXT;
|
||||
|
||||
struct _SMARTCARD_DEVICE
|
||||
{
|
||||
DEVICE device;
|
||||
@ -97,7 +108,9 @@ struct _SMARTCARD_DEVICE
|
||||
wListDictionary* rgSCardContextList;
|
||||
wListDictionary* rgOutstandingMessages;
|
||||
};
|
||||
typedef struct _SMARTCARD_DEVICE 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);
|
||||
|
@ -163,8 +163,12 @@ static UINT32 smartcard_EstablishContext(SMARTCARD_DEVICE* smartcard, IRP* irp)
|
||||
|
||||
if (ret.ReturnCode == SCARD_S_SUCCESS)
|
||||
{
|
||||
SMARTCARD_CONTEXT* pContext;
|
||||
void* key = (void*) (size_t) hContext;
|
||||
ListDictionary_Add(smartcard->rgSCardContextList, key, key);
|
||||
|
||||
pContext = smartcard_context_new(smartcard, hContext);
|
||||
|
||||
ListDictionary_Add(smartcard->rgSCardContextList, key, (void*) pContext);
|
||||
}
|
||||
|
||||
smartcard_scard_context_native_to_redir(smartcard, &(ret.hContext), hContext);
|
||||
@ -199,8 +203,12 @@ static UINT32 smartcard_ReleaseContext(SMARTCARD_DEVICE* smartcard, IRP* irp)
|
||||
|
||||
if (ret.ReturnCode == SCARD_S_SUCCESS)
|
||||
{
|
||||
SMARTCARD_CONTEXT* pContext;
|
||||
void* key = (void*) (size_t) hContext;
|
||||
ListDictionary_Remove(smartcard->rgSCardContextList, key);
|
||||
|
||||
pContext = (SMARTCARD_CONTEXT*) ListDictionary_Remove(smartcard->rgSCardContextList, key);
|
||||
|
||||
smartcard_context_free(pContext);
|
||||
}
|
||||
|
||||
smartcard_trace_long_return(smartcard, &ret, "ReleaseContext");
|
||||
|
Loading…
Reference in New Issue
Block a user