channels/smartcard: cancel outstanding IRPs on re-initialization

This commit is contained in:
Marc-André Moreau 2014-04-05 17:15:17 -04:00
parent 70b490d05c
commit 2aa248853a
8 changed files with 49 additions and 19 deletions

View File

@ -90,6 +90,7 @@ 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;

View File

@ -696,6 +696,8 @@ static void rdpdr_process_init(rdpdrPlugin* rdpdr)
IFCALL(device->Init, device); IFCALL(device->Init, device);
} }
free(pKeys);
} }
static void rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s) static void rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s)

View File

@ -53,30 +53,32 @@ static void smartcard_free(DEVICE* device)
/** /**
* Initialization occurs when the protocol server sends a device announce message. * Initialization occurs when the protocol server sends a device announce message.
* At that time, dwDeviceId MUST receive the unique device ID announced. * At that time, we need to cancel all outstanding IRPs.
* The OutstandingIrps list MUST be set to the empty list.
*/ */
static void smartcard_init(DEVICE* device) static void smartcard_init(DEVICE* device)
{ {
IRP* irp;
int index;
int keyCount;
ULONG_PTR* pKeys;
SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) device; SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) device;
if (ListDictionary_Count(smartcard->OutstandingIrps) > 0) if (ListDictionary_Count(smartcard->OutstandingIrps) > 0)
{ {
fprintf(stderr, "Warning: smartcard device initialized with outstanding IRPs\n"); pKeys = NULL;
} keyCount = ListDictionary_GetKeys(smartcard->OutstandingIrps, &pKeys);
fprintf(stderr, "SmartCard Init\n"); for (index = 0; index < keyCount; index++)
}
IRP* smartcard_get_outstanding_irp_by_id(SMARTCARD_DEVICE* smartcard, UINT32 completionId)
{ {
IRP* irp = NULL; irp = (IRP*) ListDictionary_GetItemValue(smartcard->OutstandingIrps, (void*) pKeys[index]);
void* key = (void*) (size_t) completionId;
irp = (IRP*) ListDictionary_GetItemValue(smartcard->OutstandingIrps, key); if (irp)
irp->cancelled = TRUE;
}
return irp; free(pKeys);
}
} }
void smartcard_complete_irp(SMARTCARD_DEVICE* smartcard, IRP* irp) void smartcard_complete_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
@ -86,7 +88,10 @@ void smartcard_complete_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
key = (void*) (size_t) irp->CompletionId; key = (void*) (size_t) irp->CompletionId;
ListDictionary_Remove(smartcard->OutstandingIrps, key); ListDictionary_Remove(smartcard->OutstandingIrps, key);
if (!irp->cancelled)
irp->Complete(irp); irp->Complete(irp);
else
irp->Discard(irp);
} }
static void smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp) static void smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
@ -99,7 +104,7 @@ static void smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
switch (irp->MajorFunction) switch (irp->MajorFunction)
{ {
case IRP_MJ_DEVICE_CONTROL: case IRP_MJ_DEVICE_CONTROL:
smartcard_device_control(smartcard, irp); smartcard_irp_device_control(smartcard, irp);
break; break;
default: default:

View File

@ -101,7 +101,7 @@ 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_device_control(SMARTCARD_DEVICE* smartcard, IRP* irp); void smartcard_irp_device_control(SMARTCARD_DEVICE* smartcard, IRP* irp);
#include "smartcard_pack.h" #include "smartcard_pack.h"

View File

@ -1871,7 +1871,7 @@ finish:
return status; return status;
} }
void smartcard_device_control(SMARTCARD_DEVICE* smartcard, IRP* irp) void smartcard_irp_device_control(SMARTCARD_DEVICE* smartcard, IRP* irp)
{ {
UINT32 result; UINT32 result;
UINT32 status; UINT32 status;

View File

@ -342,6 +342,7 @@ struct _IRP
UINT32 IoStatus; UINT32 IoStatus;
wStream* output; wStream* output;
BOOL cancelled;
pcIRPResponse Complete; pcIRPResponse Complete;
pcIRPResponse Discard; pcIRPResponse Discard;
}; };

View File

@ -200,6 +200,9 @@ typedef struct _wListDictionary wListDictionary;
WINPR_API int ListDictionary_Count(wListDictionary* listDictionary); WINPR_API int ListDictionary_Count(wListDictionary* listDictionary);
WINPR_API void ListDictionary_Lock(wListDictionary* listDictionary);
WINPR_API void ListDictionary_Unlock(wListDictionary* listDictionary);
WINPR_API void ListDictionary_Add(wListDictionary* listDictionary, void* key, void* value); WINPR_API void ListDictionary_Add(wListDictionary* listDictionary, void* key, void* value);
WINPR_API void* ListDictionary_Remove(wListDictionary* listDictionary, void* key); WINPR_API void* ListDictionary_Remove(wListDictionary* listDictionary, void* key);
WINPR_API void* ListDictionary_Remove_Head(wListDictionary* listDictionary); WINPR_API void* ListDictionary_Remove_Head(wListDictionary* listDictionary);

View File

@ -92,6 +92,24 @@ BOOL ListDictionary_IsSynchronized(wListDictionary* listDictionary)
return listDictionary->synchronized; return listDictionary->synchronized;
} }
/**
* Lock access to the ListDictionary
*/
void ListDictionary_Lock(wListDictionary* listDictionary)
{
EnterCriticalSection(&listDictionary->lock);
}
/**
* Unlock access to the ListDictionary
*/
void ListDictionary_Unlock(wListDictionary* listDictionary)
{
LeaveCriticalSection(&listDictionary->lock);
}
/** /**
* Methods * Methods
*/ */