channels/smartcard: add outstanding irp list

This commit is contained in:
Marc-André Moreau 2014-04-05 16:57:31 -04:00
parent 600218dfb2
commit 70b490d05c
6 changed files with 79 additions and 5 deletions

View File

@ -71,7 +71,8 @@ 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);
} }

View File

@ -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:

View File

@ -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);

View File

@ -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"

View File

@ -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);
} }

View File

@ -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;
}; };