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, irp->CompletionId); /* CompletionId (4 bytes) */
|
||||||
Stream_Write_UINT32(irp->output, 0); /* IoStatus (4 bytes) */
|
Stream_Write_UINT32(irp->output, 0); /* IoStatus (4 bytes) */
|
||||||
|
|
||||||
irp->cancelled = FALSE;
|
|
||||||
irp->Complete = irp_complete;
|
irp->Complete = irp_complete;
|
||||||
irp->Discard = irp_free;
|
irp->Discard = irp_free;
|
||||||
|
|
||||||
|
irp->thread = NULL;
|
||||||
|
irp->cancelled = FALSE;
|
||||||
|
|
||||||
return irp;
|
return irp;
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,8 @@
|
|||||||
|
|
||||||
#include "smartcard_main.h"
|
#include "smartcard_main.h"
|
||||||
|
|
||||||
|
#define SMARTCARD_ASYNC_IRP 1
|
||||||
|
|
||||||
static void smartcard_free(DEVICE* device)
|
static void smartcard_free(DEVICE* device)
|
||||||
{
|
{
|
||||||
SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) device;
|
SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) device;
|
||||||
@ -94,25 +96,16 @@ void smartcard_complete_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
|
|||||||
irp->Discard(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;
|
smartcard = (SMARTCARD_DEVICE*) irp->device;
|
||||||
ListDictionary_Add(smartcard->OutstandingIrps, key, irp);
|
|
||||||
|
|
||||||
switch (irp->MajorFunction)
|
smartcard_irp_device_control(smartcard, irp);
|
||||||
{
|
|
||||||
case IRP_MJ_DEVICE_CONTROL:
|
|
||||||
smartcard_irp_device_control(smartcard, irp);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
ExitThread(0);
|
||||||
fprintf(stderr, "MajorFunction 0x%X unexpected for smartcards.", irp->MajorFunction);
|
return NULL;
|
||||||
irp->IoStatus = STATUS_NOT_SUPPORTED;
|
|
||||||
smartcard_complete_irp(smartcard, irp);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -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
|
* 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)
|
static void* smartcard_thread_func(void* arg)
|
||||||
{
|
{
|
||||||
IRP* irp;
|
IRP* irp;
|
||||||
|
@ -100,8 +100,10 @@ struct _SMARTCARD_DEVICE
|
|||||||
typedef struct _SMARTCARD_DEVICE SMARTCARD_DEVICE;
|
typedef struct _SMARTCARD_DEVICE SMARTCARD_DEVICE;
|
||||||
|
|
||||||
void smartcard_complete_irp(SMARTCARD_DEVICE* smartcard, IRP* irp);
|
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(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"
|
#include "smartcard_pack.h"
|
||||||
|
|
||||||
|
@ -1871,6 +1871,23 @@ finish:
|
|||||||
return status;
|
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)
|
void smartcard_irp_device_control(SMARTCARD_DEVICE* smartcard, IRP* irp)
|
||||||
{
|
{
|
||||||
UINT32 result;
|
UINT32 result;
|
||||||
|
@ -342,9 +342,11 @@ struct _IRP
|
|||||||
UINT32 IoStatus;
|
UINT32 IoStatus;
|
||||||
wStream* output;
|
wStream* output;
|
||||||
|
|
||||||
BOOL cancelled;
|
|
||||||
pcIRPResponse Complete;
|
pcIRPResponse Complete;
|
||||||
pcIRPResponse Discard;
|
pcIRPResponse Discard;
|
||||||
|
|
||||||
|
HANDLE thread;
|
||||||
|
BOOL cancelled;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _DEVMAN
|
struct _DEVMAN
|
||||||
|
Loading…
Reference in New Issue
Block a user