channels/smartcard: add sequence id to IRPs for easier cancellation

This commit is contained in:
Marc-André Moreau 2014-05-06 18:19:54 -04:00
parent 62395f7b0c
commit d53a9415ae
5 changed files with 25 additions and 27 deletions

View File

@ -47,14 +47,20 @@ static void irp_free(IRP* irp)
static void irp_complete(IRP* irp)
{
int pos;
rdpdrPlugin* rdpdr;
pos = (int) Stream_GetPosition(irp->output);
Stream_SetPosition(irp->output, RDPDR_DEVICE_IO_RESPONSE_LENGTH - 4);
Stream_Write_UINT32(irp->output, irp->IoStatus); /* IoStatus (4 bytes) */
Stream_SetPosition(irp->output, pos);
rdpdr = (rdpdrPlugin*) irp->devman->plugin;
rdpdr_send((rdpdrPlugin*) irp->devman->plugin, irp->output);
irp->output = NULL;
if (irp->sequenceId == rdpdr->sequenceId)
{
pos = (int) Stream_GetPosition(irp->output);
Stream_SetPosition(irp->output, RDPDR_DEVICE_IO_RESPONSE_LENGTH - 4);
Stream_Write_UINT32(irp->output, irp->IoStatus); /* IoStatus (4 bytes) */
Stream_SetPosition(irp->output, pos);
rdpdr_send((rdpdrPlugin*) irp->devman->plugin, irp->output);
irp->output = NULL;
}
irp_free(irp);
}
@ -64,6 +70,7 @@ IRP* irp_new(DEVMAN* devman, wStream* s)
IRP* irp;
DEVICE* device;
UINT32 DeviceId;
rdpdrPlugin* rdpdr;
Stream_Read_UINT32(s, DeviceId); /* DeviceId (4 bytes) */
device = devman_get_device_by_id(devman, DeviceId);
@ -71,6 +78,8 @@ IRP* irp_new(DEVMAN* devman, wStream* s)
if (!device)
return NULL;
rdpdr = (rdpdrPlugin*) devman->plugin;
irp = (IRP*) _aligned_malloc(sizeof(IRP), MEMORY_ALLOCATION_ALIGNMENT);
ZeroMemory(irp, sizeof(IRP));
@ -96,5 +105,7 @@ IRP* irp_new(DEVMAN* devman, wStream* s)
irp->thread = NULL;
irp->cancelled = FALSE;
irp->sequenceId = rdpdr->sequenceId;
return irp;
}

View File

@ -517,6 +517,8 @@ static void rdpdr_process_server_announce_request(rdpdrPlugin* rdpdr, wStream* s
Stream_Read_UINT16(s, rdpdr->versionMajor);
Stream_Read_UINT16(s, rdpdr->versionMinor);
Stream_Read_UINT32(s, rdpdr->clientID);
rdpdr->sequenceId++;
}
static void rdpdr_send_client_announce_reply(rdpdrPlugin* rdpdr)
@ -1034,6 +1036,8 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
strcpy(rdpdr->channelDef.name, "rdpdr");
rdpdr->sequenceId = 0;
CopyMemory(&(rdpdr->channelEntryPoints), pEntryPoints, sizeof(CHANNEL_ENTRY_POINTS_FREERDP));
rdpdr->channelEntryPoints.pVirtualChannelInit(&rdpdr->InitHandle,

View File

@ -53,6 +53,8 @@ struct rdpdr_plugin
UINT16 clientID;
char computerName[256];
UINT32 sequenceId;
/* hotplug support */
HANDLE hotplugThread;
#ifdef _WIN32

View File

@ -62,7 +62,6 @@ static void smartcard_free(DEVICE* device)
static void smartcard_init(DEVICE* device)
{
IRP* irp;
int index;
int keyCount;
ULONG_PTR* pKeys;
@ -70,22 +69,6 @@ static void smartcard_init(DEVICE* device)
SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) device;
if (ListDictionary_Count(smartcard->rgOutstandingMessages) > 0)
{
pKeys = NULL;
keyCount = ListDictionary_GetKeys(smartcard->rgOutstandingMessages, &pKeys);
for (index = 0; index < keyCount; index++)
{
irp = (IRP*) ListDictionary_GetItemValue(smartcard->rgOutstandingMessages, (void*) pKeys[index]);
if (irp)
irp->cancelled = TRUE;
}
free(pKeys);
}
/**
* On protocol termination, the following actions are performed:
* For each context in rgSCardContextList, SCardCancel is called causing all outstanding messages to be processed.
@ -116,10 +99,7 @@ void smartcard_complete_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
key = (void*) (size_t) irp->CompletionId;
ListDictionary_Remove(smartcard->rgOutstandingMessages, key);
if (!irp->cancelled)
irp->Complete(irp);
else
irp->Discard(irp);
irp->Complete(irp);
}
void* smartcard_process_irp_worker_proc(IRP* irp)

View File

@ -349,6 +349,7 @@ struct _IRP
HANDLE thread;
BOOL cancelled;
UINT32 sequenceId;
};
struct _DEVMAN