channels/smartcard: add async irp processing
This commit is contained in:
parent
2aa248853a
commit
9de2a85f6a
@ -90,9 +90,11 @@ IRP* irp_new(DEVMAN* devman, wStream* s)
|
||||
Stream_Write_UINT32(irp->output, irp->CompletionId); /* CompletionId (4 bytes) */
|
||||
Stream_Write_UINT32(irp->output, 0); /* IoStatus (4 bytes) */
|
||||
|
||||
irp->cancelled = FALSE;
|
||||
irp->Complete = irp_complete;
|
||||
irp->Discard = irp_free;
|
||||
|
||||
irp->thread = NULL;
|
||||
irp->cancelled = FALSE;
|
||||
|
||||
return irp;
|
||||
}
|
||||
|
@ -34,6 +34,8 @@
|
||||
|
||||
#include "smartcard_main.h"
|
||||
|
||||
#define SMARTCARD_ASYNC_IRP 1
|
||||
|
||||
static void smartcard_free(DEVICE* device)
|
||||
{
|
||||
SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) device;
|
||||
@ -94,25 +96,16 @@ void smartcard_complete_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
|
||||
irp->Discard(irp);
|
||||
}
|
||||
|
||||
static void smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
|
||||
void* smartcard_process_irp_worker_proc(IRP* irp)
|
||||
{
|
||||
void* key;
|
||||
SMARTCARD_DEVICE* smartcard;
|
||||
|
||||
key = (void*) (size_t) irp->CompletionId;
|
||||
ListDictionary_Add(smartcard->OutstandingIrps, key, irp);
|
||||
smartcard = (SMARTCARD_DEVICE*) irp->device;
|
||||
|
||||
switch (irp->MajorFunction)
|
||||
{
|
||||
case IRP_MJ_DEVICE_CONTROL:
|
||||
smartcard_irp_device_control(smartcard, irp);
|
||||
break;
|
||||
smartcard_irp_device_control(smartcard, irp);
|
||||
|
||||
default:
|
||||
fprintf(stderr, "MajorFunction 0x%X unexpected for smartcards.", irp->MajorFunction);
|
||||
irp->IoStatus = STATUS_NOT_SUPPORTED;
|
||||
smartcard_complete_irp(smartcard, irp);
|
||||
break;
|
||||
}
|
||||
ExitThread(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -120,6 +113,55 @@ static void smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
|
||||
* http://musclecard.996296.n3.nabble.com/Multiple-threads-and-SCardGetStatusChange-td4430.html
|
||||
*/
|
||||
|
||||
void smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
|
||||
{
|
||||
void* key;
|
||||
BOOL asyncIrp = FALSE;
|
||||
UINT32 ioControlCode = 0;
|
||||
|
||||
key = (void*) (size_t) irp->CompletionId;
|
||||
ListDictionary_Add(smartcard->OutstandingIrps, key, irp);
|
||||
|
||||
if (irp->MajorFunction == IRP_MJ_DEVICE_CONTROL)
|
||||
{
|
||||
smartcard_irp_device_control_peek_io_control_code(smartcard, irp, &ioControlCode);
|
||||
|
||||
#ifdef SMARTCARD_ASYNC_IRP
|
||||
if (!ioControlCode)
|
||||
return;
|
||||
|
||||
switch (ioControlCode)
|
||||
{
|
||||
case SCARD_IOCTL_TRANSMIT:
|
||||
case SCARD_IOCTL_STATUSA:
|
||||
case SCARD_IOCTL_STATUSW:
|
||||
case SCARD_IOCTL_GETSTATUSCHANGEA:
|
||||
case SCARD_IOCTL_GETSTATUSCHANGEW:
|
||||
asyncIrp = TRUE;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!asyncIrp)
|
||||
{
|
||||
smartcard_irp_device_control(smartcard, irp);
|
||||
}
|
||||
else
|
||||
{
|
||||
irp->thread = CreateThread(NULL, 0,
|
||||
(LPTHREAD_START_ROUTINE) smartcard_process_irp_worker_proc,
|
||||
irp, 0, NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Unexpected SmartCard IRP: MajorFunction 0x%08X MinorFunction: 0x%08X",
|
||||
irp->MajorFunction, irp->MinorFunction);
|
||||
irp->IoStatus = STATUS_NOT_SUPPORTED;
|
||||
smartcard_complete_irp(smartcard, irp);
|
||||
}
|
||||
}
|
||||
|
||||
static void* smartcard_thread_func(void* arg)
|
||||
{
|
||||
IRP* irp;
|
||||
|
@ -100,8 +100,10 @@ struct _SMARTCARD_DEVICE
|
||||
typedef struct _SMARTCARD_DEVICE SMARTCARD_DEVICE;
|
||||
|
||||
void smartcard_complete_irp(SMARTCARD_DEVICE* smartcard, IRP* irp);
|
||||
void smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp);
|
||||
|
||||
void smartcard_irp_device_control(SMARTCARD_DEVICE* smartcard, IRP* irp);
|
||||
void smartcard_irp_device_control_peek_io_control_code(SMARTCARD_DEVICE* smartcard, IRP* irp, UINT32* ioControlCode);
|
||||
|
||||
#include "smartcard_pack.h"
|
||||
|
||||
|
@ -1871,6 +1871,23 @@ finish:
|
||||
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));
|
||||
}
|
||||
|
||||
void smartcard_irp_device_control(SMARTCARD_DEVICE* smartcard, IRP* irp)
|
||||
{
|
||||
UINT32 result;
|
||||
|
@ -342,9 +342,11 @@ struct _IRP
|
||||
UINT32 IoStatus;
|
||||
wStream* output;
|
||||
|
||||
BOOL cancelled;
|
||||
pcIRPResponse Complete;
|
||||
pcIRPResponse Discard;
|
||||
|
||||
HANDLE thread;
|
||||
BOOL cancelled;
|
||||
};
|
||||
|
||||
struct _DEVMAN
|
||||
|
Loading…
Reference in New Issue
Block a user