mirror of https://github.com/FreeRDP/FreeRDP
channels/smartcard: add outstanding irp list
This commit is contained in:
parent
600218dfb2
commit
70b490d05c
|
@ -72,6 +72,7 @@ void devman_unregister_device(DEVMAN* devman, void* key)
|
||||||
DEVICE* device;
|
DEVICE* device;
|
||||||
|
|
||||||
device = (DEVICE*) ListDictionary_Remove(devman->devices, key);
|
device = (DEVICE*) ListDictionary_Remove(devman->devices, key);
|
||||||
|
|
||||||
if (device)
|
if (device)
|
||||||
devman_device_free(device);
|
devman_device_free(device);
|
||||||
}
|
}
|
||||||
|
|
|
@ -680,6 +680,24 @@ static BOOL rdpdr_process_irp(rdpdrPlugin* rdpdr, wStream* s)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rdpdr_process_init(rdpdrPlugin* rdpdr)
|
||||||
|
{
|
||||||
|
int index;
|
||||||
|
int keyCount;
|
||||||
|
DEVICE* device;
|
||||||
|
ULONG_PTR* pKeys;
|
||||||
|
|
||||||
|
pKeys = NULL;
|
||||||
|
keyCount = ListDictionary_GetKeys(rdpdr->devman->devices, &pKeys);
|
||||||
|
|
||||||
|
for (index = 0; index < keyCount; index++)
|
||||||
|
{
|
||||||
|
device = (DEVICE*) ListDictionary_GetItemValue(rdpdr->devman->devices, (void*) pKeys[index]);
|
||||||
|
|
||||||
|
IFCALL(device->Init, device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s)
|
static void rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s)
|
||||||
{
|
{
|
||||||
UINT16 component;
|
UINT16 component;
|
||||||
|
@ -698,6 +716,7 @@ static void rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s)
|
||||||
rdpdr_process_server_announce_request(rdpdr, s);
|
rdpdr_process_server_announce_request(rdpdr, s);
|
||||||
rdpdr_send_client_announce_reply(rdpdr);
|
rdpdr_send_client_announce_reply(rdpdr);
|
||||||
rdpdr_send_client_name_request(rdpdr);
|
rdpdr_send_client_name_request(rdpdr);
|
||||||
|
rdpdr_process_init(rdpdr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PAKID_CORE_SERVER_CAPABILITY:
|
case PAKID_CORE_SERVER_CAPABILITY:
|
||||||
|
|
|
@ -45,11 +45,57 @@ static void smartcard_free(DEVICE* device)
|
||||||
|
|
||||||
Stream_Free(smartcard->device.data, TRUE);
|
Stream_Free(smartcard->device.data, TRUE);
|
||||||
|
|
||||||
|
MessageQueue_Free(smartcard->IrpQueue);
|
||||||
|
ListDictionary_Free(smartcard->OutstandingIrps);
|
||||||
|
|
||||||
free(device);
|
free(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialization occurs when the protocol server sends a device announce message.
|
||||||
|
* At that time, dwDeviceId MUST receive the unique device ID announced.
|
||||||
|
* The OutstandingIrps list MUST be set to the empty list.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void smartcard_init(DEVICE* device)
|
||||||
|
{
|
||||||
|
SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) device;
|
||||||
|
|
||||||
|
if (ListDictionary_Count(smartcard->OutstandingIrps) > 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Warning: smartcard device initialized with outstanding IRPs\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "SmartCard Init\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
IRP* smartcard_get_outstanding_irp_by_id(SMARTCARD_DEVICE* smartcard, UINT32 completionId)
|
||||||
|
{
|
||||||
|
IRP* irp = NULL;
|
||||||
|
void* key = (void*) (size_t) completionId;
|
||||||
|
|
||||||
|
irp = (IRP*) ListDictionary_GetItemValue(smartcard->OutstandingIrps, key);
|
||||||
|
|
||||||
|
return irp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void smartcard_complete_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
|
||||||
|
{
|
||||||
|
void* key;
|
||||||
|
|
||||||
|
key = (void*) (size_t) irp->CompletionId;
|
||||||
|
ListDictionary_Remove(smartcard->OutstandingIrps, key);
|
||||||
|
|
||||||
|
irp->Complete(irp);
|
||||||
|
}
|
||||||
|
|
||||||
static void smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
|
static void smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
|
||||||
{
|
{
|
||||||
|
void* key;
|
||||||
|
|
||||||
|
key = (void*) (size_t) irp->CompletionId;
|
||||||
|
ListDictionary_Add(smartcard->OutstandingIrps, key, irp);
|
||||||
|
|
||||||
switch (irp->MajorFunction)
|
switch (irp->MajorFunction)
|
||||||
{
|
{
|
||||||
case IRP_MJ_DEVICE_CONTROL:
|
case IRP_MJ_DEVICE_CONTROL:
|
||||||
|
@ -59,7 +105,7 @@ static void smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "MajorFunction 0x%X unexpected for smartcards.", irp->MajorFunction);
|
fprintf(stderr, "MajorFunction 0x%X unexpected for smartcards.", irp->MajorFunction);
|
||||||
irp->IoStatus = STATUS_NOT_SUPPORTED;
|
irp->IoStatus = STATUS_NOT_SUPPORTED;
|
||||||
irp->Complete(irp);
|
smartcard_complete_irp(smartcard, irp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,6 +173,7 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
|
||||||
smartcard->device.type = RDPDR_DTYP_SMARTCARD;
|
smartcard->device.type = RDPDR_DTYP_SMARTCARD;
|
||||||
smartcard->device.name = "SCARD";
|
smartcard->device.name = "SCARD";
|
||||||
smartcard->device.IRPRequest = smartcard_irp_request;
|
smartcard->device.IRPRequest = smartcard_irp_request;
|
||||||
|
smartcard->device.Init = smartcard_init;
|
||||||
smartcard->device.Free = smartcard_free;
|
smartcard->device.Free = smartcard_free;
|
||||||
|
|
||||||
length = strlen(smartcard->device.name);
|
length = strlen(smartcard->device.name);
|
||||||
|
@ -153,6 +200,8 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
|
||||||
smartcard->log = WLog_Get("com.freerdp.channel.smartcard.client");
|
smartcard->log = WLog_Get("com.freerdp.channel.smartcard.client");
|
||||||
|
|
||||||
smartcard->IrpQueue = MessageQueue_New(NULL);
|
smartcard->IrpQueue = MessageQueue_New(NULL);
|
||||||
|
smartcard->OutstandingIrps = 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,12 +92,15 @@ struct _SMARTCARD_DEVICE
|
||||||
|
|
||||||
HANDLE thread;
|
HANDLE thread;
|
||||||
wMessageQueue* IrpQueue;
|
wMessageQueue* IrpQueue;
|
||||||
|
wListDictionary* OutstandingIrps;
|
||||||
|
|
||||||
SCARDCONTEXT hContext;
|
SCARDCONTEXT hContext;
|
||||||
SCARDHANDLE hCard;
|
SCARDHANDLE hCard;
|
||||||
};
|
};
|
||||||
typedef struct _SMARTCARD_DEVICE SMARTCARD_DEVICE;
|
typedef struct _SMARTCARD_DEVICE SMARTCARD_DEVICE;
|
||||||
|
|
||||||
|
void smartcard_complete_irp(SMARTCARD_DEVICE* smartcard, IRP* irp);
|
||||||
|
|
||||||
void smartcard_device_control(SMARTCARD_DEVICE* smartcard, IRP* irp);
|
void smartcard_device_control(SMARTCARD_DEVICE* smartcard, IRP* irp);
|
||||||
|
|
||||||
#include "smartcard_pack.h"
|
#include "smartcard_pack.h"
|
||||||
|
|
|
@ -1902,8 +1902,8 @@ void smartcard_device_control(SMARTCARD_DEVICE* smartcard, IRP* irp)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
WLog_Print(smartcard->log, WLOG_WARN, "ioControlCode: %s (0x%08X)",
|
WLog_Print(smartcard->log, WLOG_WARN, "ioControlCode: %s (0x%08X) FileId: %d CompletionId: %d",
|
||||||
smartcard_get_ioctl_string(ioControlCode), ioControlCode);
|
smartcard_get_ioctl_string(ioControlCode), ioControlCode, irp->FileId, irp->CompletionId);
|
||||||
|
|
||||||
if ((ioControlCode != SCARD_IOCTL_ACCESSSTARTEDEVENT) &&
|
if ((ioControlCode != SCARD_IOCTL_ACCESSSTARTEDEVENT) &&
|
||||||
(ioControlCode != SCARD_IOCTL_RELEASESTARTEDEVENT))
|
(ioControlCode != SCARD_IOCTL_RELEASESTARTEDEVENT))
|
||||||
|
@ -2159,5 +2159,5 @@ void smartcard_device_control(SMARTCARD_DEVICE* smartcard, IRP* irp)
|
||||||
Stream_SetPosition(irp->output, Stream_Length(irp->output));
|
Stream_SetPosition(irp->output, Stream_Length(irp->output));
|
||||||
|
|
||||||
irp->IoStatus = 0;
|
irp->IoStatus = 0;
|
||||||
irp->Complete(irp);
|
smartcard_complete_irp(smartcard, irp);
|
||||||
}
|
}
|
||||||
|
|
|
@ -309,6 +309,7 @@ typedef struct _IRP IRP;
|
||||||
typedef struct _DEVMAN DEVMAN;
|
typedef struct _DEVMAN DEVMAN;
|
||||||
|
|
||||||
typedef void (*pcIRPRequest)(DEVICE* device, IRP* irp);
|
typedef void (*pcIRPRequest)(DEVICE* device, IRP* irp);
|
||||||
|
typedef void (*pcInitDevice)(DEVICE* device);
|
||||||
typedef void (*pcFreeDevice)(DEVICE* device);
|
typedef void (*pcFreeDevice)(DEVICE* device);
|
||||||
|
|
||||||
struct _DEVICE
|
struct _DEVICE
|
||||||
|
@ -320,6 +321,7 @@ struct _DEVICE
|
||||||
wStream* data;
|
wStream* data;
|
||||||
|
|
||||||
pcIRPRequest IRPRequest;
|
pcIRPRequest IRPRequest;
|
||||||
|
pcInitDevice Init;
|
||||||
pcFreeDevice Free;
|
pcFreeDevice Free;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue