channels/smartcard: cleanup smartcard operations

This commit is contained in:
Marc-André Moreau 2014-05-12 15:47:49 -04:00
parent 5416ab1d6e
commit d8053b3d93
3 changed files with 48 additions and 64 deletions

View File

@ -35,14 +35,6 @@
#include "smartcard_main.h"
struct _SMARTCARD_IRP_WORK
{
IRP* irp;
ULONG_PTR* call;
UINT32 ioControlCode;
};
typedef struct _SMARTCARD_IRP_WORK SMARTCARD_IRP_WORK;
void* smartcard_context_thread(SMARTCARD_CONTEXT* pContext)
{
IRP* irp;
@ -229,25 +221,20 @@ void smartcard_complete_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
irp->Complete(irp);
}
void* smartcard_process_irp_worker_proc(SMARTCARD_IRP_WORK* irpWork)
void* smartcard_process_irp_worker_proc(SMARTCARD_OPERATION* operation)
{
IRP* irp;
UINT32 status;
ULONG_PTR* call;
UINT32 ioControlCode;
SMARTCARD_DEVICE* smartcard;
irp = irpWork->irp;
call = irpWork->call;
ioControlCode = irpWork->ioControlCode;
irp = operation->irp;
smartcard = (SMARTCARD_DEVICE*) irp->device;
status = smartcard_irp_device_control_call(smartcard, irp, ioControlCode, call);
status = smartcard_irp_device_control_call(smartcard, operation);
Queue_Enqueue(smartcard->CompletedIrpQueue, (void*) irp);
free(irpWork);
free(operation);
ExitThread(0);
return NULL;
@ -263,19 +250,31 @@ void smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
void* key;
UINT32 status;
BOOL asyncIrp = FALSE;
ULONG_PTR* call = NULL;
UINT32 ioControlCode = 0;
SMARTCARD_OPERATION* operation = NULL;
key = (void*) (size_t) irp->CompletionId;
ListDictionary_Add(smartcard->rgOutstandingMessages, key, irp);
if (irp->MajorFunction == IRP_MJ_DEVICE_CONTROL)
{
smartcard_irp_device_control_peek_io_control_code(smartcard, irp, &ioControlCode);
operation = (SMARTCARD_OPERATION*) calloc(1, sizeof(SMARTCARD_OPERATION));
if (!ioControlCode)
if (!operation)
return;
operation->irp = irp;
status = smartcard_irp_device_control_decode(smartcard, operation);
if (status != SCARD_S_SUCCESS)
{
irp->IoStatus = STATUS_UNSUCCESSFUL;
Queue_Enqueue(smartcard->CompletedIrpQueue, (void*) irp);
return;
}
asyncIrp = TRUE;
/**
@ -284,7 +283,7 @@ void smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
* those expected to return fast synchronously.
*/
switch (ioControlCode)
switch (operation->ioControlCode)
{
case SCARD_IOCTL_ESTABLISHCONTEXT:
case SCARD_IOCTL_RELEASECONTEXT:
@ -347,32 +346,17 @@ void smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
break;
}
status = smartcard_irp_device_control_decode(smartcard, irp, &ioControlCode, &call);
if (status != SCARD_S_SUCCESS)
{
/* TODO: properly handle decoding failure response */
fprintf(stderr, "fixme: properly handle decoding failure response\n");
}
if (!asyncIrp)
{
status = smartcard_irp_device_control_call(smartcard, irp, ioControlCode, call);
status = smartcard_irp_device_control_call(smartcard, operation);
Queue_Enqueue(smartcard->CompletedIrpQueue, (void*) irp);
free(operation);
}
else
{
SMARTCARD_IRP_WORK* irpWork;
irpWork = (SMARTCARD_IRP_WORK*) calloc(1, sizeof(SMARTCARD_IRP_WORK));
irpWork->irp = irp;
irpWork->call = call;
irpWork->ioControlCode = ioControlCode;
irp->thread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE) smartcard_process_irp_worker_proc,
irpWork, 0, NULL);
operation, 0, NULL);
}
}
else

View File

@ -83,6 +83,14 @@
typedef struct _SMARTCARD_DEVICE SMARTCARD_DEVICE;
struct _SMARTCARD_OPERATION
{
IRP* irp;
void* call;
UINT32 ioControlCode;
};
typedef struct _SMARTCARD_OPERATION SMARTCARD_OPERATION;
struct _SMARTCARD_CONTEXT
{
HANDLE thread;
@ -115,9 +123,8 @@ 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);
UINT32 smartcard_irp_device_control_decode(SMARTCARD_DEVICE* smartcard, IRP* irp, UINT32* pIoControlCode, ULONG_PTR** ppCall);
UINT32 smartcard_irp_device_control_call(SMARTCARD_DEVICE* smartcard, IRP* irp, UINT32 ioControlCode, ULONG_PTR* call);
void smartcard_irp_device_control_peek_io_control_code(SMARTCARD_DEVICE* smartcard, IRP* irp, UINT32* ioControlCode);
UINT32 smartcard_irp_device_control_decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation);
UINT32 smartcard_irp_device_control_call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation);
#include "smartcard_pack.h"

View File

@ -1092,25 +1092,9 @@ static UINT32 smartcard_AccessStartedEvent_Call(SMARTCARD_DEVICE* smartcard, IRP
return status;
}
void smartcard_irp_device_control_peek_io_control_code(SMARTCARD_DEVICE* smartcard, IRP* irp, UINT32* ioControlCode)
{
*ioControlCode = 0;
if (Stream_GetRemainingLength(irp->input) < 32)
{
WLog_Print(smartcard->log, WLOG_WARN, "Device Control Request is too short: %d",
(int) Stream_GetRemainingLength(irp->input));
return;
}
Stream_Seek_UINT32(irp->input); /* OutputBufferLength (4 bytes) */
Stream_Seek_UINT32(irp->input); /* InputBufferLength (4 bytes) */
Stream_Read_UINT32(irp->input, *ioControlCode); /* IoControlCode (4 bytes) */
Stream_Rewind(irp->input, (4 + 4 + 4));
}
UINT32 smartcard_irp_device_control_decode(SMARTCARD_DEVICE* smartcard, IRP* irp, UINT32* pIoControlCode, ULONG_PTR** ppCall)
UINT32 smartcard_irp_device_control_decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation)
{
IRP* irp;
UINT32 status;
UINT32 offset;
void* call = NULL;
@ -1118,6 +1102,8 @@ UINT32 smartcard_irp_device_control_decode(SMARTCARD_DEVICE* smartcard, IRP* irp
UINT32 outputBufferLength;
UINT32 inputBufferLength;
irp = operation->irp;
/* Device Control Request */
if (Stream_GetRemainingLength(irp->input) < 32)
@ -1132,7 +1118,7 @@ UINT32 smartcard_irp_device_control_decode(SMARTCARD_DEVICE* smartcard, IRP* irp
Stream_Read_UINT32(irp->input, ioControlCode); /* IoControlCode (4 bytes) */
Stream_Seek(irp->input, 20); /* Padding (20 bytes) */
*pIoControlCode = ioControlCode;
operation->ioControlCode = ioControlCode;
if (Stream_Length(irp->input) != (Stream_GetPosition(irp->input) + inputBufferLength))
{
@ -1427,18 +1413,25 @@ UINT32 smartcard_irp_device_control_decode(SMARTCARD_DEVICE* smartcard, IRP* irp
call = NULL;
}
*((ULONG_PTR**) ppCall) = (ULONG_PTR*) call;
operation->call = call;
return status;
}
UINT32 smartcard_irp_device_control_call(SMARTCARD_DEVICE* smartcard, IRP* irp, UINT32 ioControlCode, ULONG_PTR* call)
UINT32 smartcard_irp_device_control_call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation)
{
IRP* irp;
UINT32 result;
UINT32 offset;
ULONG_PTR* call;
UINT32 ioControlCode;
UINT32 outputBufferLength;
UINT32 objectBufferLength;
irp = operation->irp;
call = operation->call;
ioControlCode = operation->ioControlCode;
/**
* [MS-RDPESC] 3.2.5.1: Sending Outgoing Messages:
* the output buffer length SHOULD be set to 2048