channels: patch rdpdr/smartcard valgrind leaks, fix hang on disconnect
This commit is contained in:
parent
5024c42b76
commit
51554ff16c
@ -75,6 +75,10 @@ IRP* irp_new(DEVMAN* devman, wStream* s)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
irp = (IRP*) _aligned_malloc(sizeof(IRP), MEMORY_ALLOCATION_ALIGNMENT);
|
irp = (IRP*) _aligned_malloc(sizeof(IRP), MEMORY_ALLOCATION_ALIGNMENT);
|
||||||
|
|
||||||
|
if (!irp)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
ZeroMemory(irp, sizeof(IRP));
|
ZeroMemory(irp, sizeof(IRP));
|
||||||
|
|
||||||
irp->input = s;
|
irp->input = s;
|
||||||
|
@ -539,8 +539,8 @@ static void rdpdr_send_client_announce_reply(rdpdrPlugin* rdpdr)
|
|||||||
|
|
||||||
s = Stream_New(NULL, 12);
|
s = Stream_New(NULL, 12);
|
||||||
|
|
||||||
Stream_Write_UINT16(s, RDPDR_CTYP_CORE);
|
Stream_Write_UINT16(s, RDPDR_CTYP_CORE); /* Component (2 bytes) */
|
||||||
Stream_Write_UINT16(s, PAKID_CORE_CLIENTID_CONFIRM);
|
Stream_Write_UINT16(s, PAKID_CORE_CLIENTID_CONFIRM); /* PacketId (2 bytes) */
|
||||||
|
|
||||||
Stream_Write_UINT16(s, rdpdr->versionMajor);
|
Stream_Write_UINT16(s, rdpdr->versionMajor);
|
||||||
Stream_Write_UINT16(s, rdpdr->versionMinor);
|
Stream_Write_UINT16(s, rdpdr->versionMinor);
|
||||||
@ -562,8 +562,8 @@ static void rdpdr_send_client_name_request(rdpdrPlugin* rdpdr)
|
|||||||
|
|
||||||
s = Stream_New(NULL, 16 + computerNameLenW + 2);
|
s = Stream_New(NULL, 16 + computerNameLenW + 2);
|
||||||
|
|
||||||
Stream_Write_UINT16(s, RDPDR_CTYP_CORE);
|
Stream_Write_UINT16(s, RDPDR_CTYP_CORE); /* Component (2 bytes) */
|
||||||
Stream_Write_UINT16(s, PAKID_CORE_CLIENT_NAME);
|
Stream_Write_UINT16(s, PAKID_CORE_CLIENT_NAME); /* PacketId (2 bytes) */
|
||||||
|
|
||||||
Stream_Write_UINT32(s, 1); /* unicodeFlag, 0 for ASCII and 1 for Unicode */
|
Stream_Write_UINT32(s, 1); /* unicodeFlag, 0 for ASCII and 1 for Unicode */
|
||||||
Stream_Write_UINT32(s, 0); /* codePage, must be set to zero */
|
Stream_Write_UINT32(s, 0); /* codePage, must be set to zero */
|
||||||
@ -614,8 +614,8 @@ static void rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, BOOL use
|
|||||||
|
|
||||||
s = Stream_New(NULL, 256);
|
s = Stream_New(NULL, 256);
|
||||||
|
|
||||||
Stream_Write_UINT16(s, RDPDR_CTYP_CORE);
|
Stream_Write_UINT16(s, RDPDR_CTYP_CORE); /* Component (2 bytes) */
|
||||||
Stream_Write_UINT16(s, PAKID_CORE_DEVICELIST_ANNOUNCE);
|
Stream_Write_UINT16(s, PAKID_CORE_DEVICELIST_ANNOUNCE); /* PacketId (2 bytes) */
|
||||||
|
|
||||||
count_pos = (int) Stream_GetPosition(s);
|
count_pos = (int) Stream_GetPosition(s);
|
||||||
count = 0;
|
count = 0;
|
||||||
@ -716,16 +716,16 @@ static void rdpdr_process_init(rdpdrPlugin* rdpdr)
|
|||||||
static void rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s)
|
static void rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s)
|
||||||
{
|
{
|
||||||
UINT16 component;
|
UINT16 component;
|
||||||
UINT16 packetID;
|
UINT16 packetId;
|
||||||
UINT32 deviceID;
|
UINT32 deviceId;
|
||||||
UINT32 status;
|
UINT32 status;
|
||||||
|
|
||||||
Stream_Read_UINT16(s, component);
|
Stream_Read_UINT16(s, component); /* Component (2 bytes) */
|
||||||
Stream_Read_UINT16(s, packetID);
|
Stream_Read_UINT16(s, packetId); /* PacketId (2 bytes) */
|
||||||
|
|
||||||
if (component == RDPDR_CTYP_CORE)
|
if (component == RDPDR_CTYP_CORE)
|
||||||
{
|
{
|
||||||
switch (packetID)
|
switch (packetId)
|
||||||
{
|
{
|
||||||
case PAKID_CORE_SERVER_ANNOUNCE:
|
case PAKID_CORE_SERVER_ANNOUNCE:
|
||||||
rdpdr_process_server_announce_request(rdpdr, s);
|
rdpdr_process_server_announce_request(rdpdr, s);
|
||||||
@ -750,7 +750,7 @@ static void rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s)
|
|||||||
|
|
||||||
case PAKID_CORE_DEVICE_REPLY:
|
case PAKID_CORE_DEVICE_REPLY:
|
||||||
/* connect to a specific resource */
|
/* connect to a specific resource */
|
||||||
Stream_Read_UINT32(s, deviceID);
|
Stream_Read_UINT32(s, deviceId);
|
||||||
Stream_Read_UINT32(s, status);
|
Stream_Read_UINT32(s, status);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -760,17 +760,19 @@ static void rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
WLog_ERR(TAG, "rdpdr_process_receive: RDPDR_CTYP_CORE unknown PacketId: 0x%04X", packetId);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (component == RDPDR_CTYP_PRN)
|
else if (component == RDPDR_CTYP_PRN)
|
||||||
{
|
{
|
||||||
|
WLog_ERR(TAG, "rdpdr_process_receive: RDPDR_CTYP_PRN unknown PacketId: 0x%04X", packetId);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
WLog_ERR(TAG, "rdpdr_process_receive: unknown message: Component: 0x%04X PacketId: 0x%04X",
|
||||||
|
component, packetId);
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream_Free(s, TRUE);
|
Stream_Free(s, TRUE);
|
||||||
@ -869,7 +871,7 @@ static void rdpdr_virtual_channel_event_data_received(rdpdrPlugin* rdpdr,
|
|||||||
|
|
||||||
if (dataFlags & CHANNEL_FLAG_FIRST)
|
if (dataFlags & CHANNEL_FLAG_FIRST)
|
||||||
{
|
{
|
||||||
if (rdpdr->data_in != NULL)
|
if (rdpdr->data_in)
|
||||||
Stream_Free(rdpdr->data_in, TRUE);
|
Stream_Free(rdpdr->data_in, TRUE);
|
||||||
|
|
||||||
rdpdr->data_in = Stream_New(NULL, totalLength);
|
rdpdr->data_in = Stream_New(NULL, totalLength);
|
||||||
@ -883,14 +885,14 @@ static void rdpdr_virtual_channel_event_data_received(rdpdrPlugin* rdpdr,
|
|||||||
{
|
{
|
||||||
if (Stream_Capacity(data_in) != Stream_GetPosition(data_in))
|
if (Stream_Capacity(data_in) != Stream_GetPosition(data_in))
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "svc_plugin_process_received: read error\n");
|
WLog_ERR(TAG, "rdpdr_virtual_channel_event_data_received: read error\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
rdpdr->data_in = NULL;
|
rdpdr->data_in = NULL;
|
||||||
Stream_SealLength(data_in);
|
Stream_SealLength(data_in);
|
||||||
Stream_SetPosition(data_in, 0);
|
Stream_SetPosition(data_in, 0);
|
||||||
|
|
||||||
MessageQueue_Post(rdpdr->MsgPipe->In, NULL, 0, (void*) data_in, NULL);
|
MessageQueue_Post(rdpdr->queue, NULL, 0, (void*) data_in, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -929,10 +931,10 @@ static void* rdpdr_virtual_channel_client_thread(void* arg)
|
|||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
if (!MessageQueue_Wait(rdpdr->MsgPipe->In))
|
if (!MessageQueue_Wait(rdpdr->queue))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (MessageQueue_Peek(rdpdr->MsgPipe->In, &message, TRUE))
|
if (MessageQueue_Peek(rdpdr->queue, &message, TRUE))
|
||||||
{
|
{
|
||||||
if (message.id == WMQ_QUIT)
|
if (message.id == WMQ_QUIT)
|
||||||
break;
|
break;
|
||||||
@ -964,7 +966,7 @@ static void rdpdr_virtual_channel_event_connected(rdpdrPlugin* rdpdr, LPVOID pDa
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
rdpdr->MsgPipe = MessagePipe_New();
|
rdpdr->queue = MessageQueue_New(NULL);
|
||||||
|
|
||||||
rdpdr->thread = CreateThread(NULL, 0,
|
rdpdr->thread = CreateThread(NULL, 0,
|
||||||
(LPTHREAD_START_ROUTINE) rdpdr_virtual_channel_client_thread, (void*) rdpdr, 0, NULL);
|
(LPTHREAD_START_ROUTINE) rdpdr_virtual_channel_client_thread, (void*) rdpdr, 0, NULL);
|
||||||
@ -972,13 +974,13 @@ static void rdpdr_virtual_channel_event_connected(rdpdrPlugin* rdpdr, LPVOID pDa
|
|||||||
|
|
||||||
static void rdpdr_virtual_channel_event_terminated(rdpdrPlugin* rdpdr)
|
static void rdpdr_virtual_channel_event_terminated(rdpdrPlugin* rdpdr)
|
||||||
{
|
{
|
||||||
if (rdpdr->MsgPipe)
|
if (rdpdr->queue)
|
||||||
{
|
{
|
||||||
MessagePipe_PostQuit(rdpdr->MsgPipe, 0);
|
MessageQueue_PostQuit(rdpdr->queue, 0);
|
||||||
WaitForSingleObject(rdpdr->thread, INFINITE);
|
WaitForSingleObject(rdpdr->thread, INFINITE);
|
||||||
|
|
||||||
MessagePipe_Free(rdpdr->MsgPipe);
|
MessageQueue_Free(rdpdr->queue);
|
||||||
rdpdr->MsgPipe = NULL;
|
rdpdr->queue = NULL;
|
||||||
|
|
||||||
CloseHandle(rdpdr->thread);
|
CloseHandle(rdpdr->thread);
|
||||||
rdpdr->thread = NULL;
|
rdpdr->thread = NULL;
|
||||||
|
@ -47,7 +47,7 @@ struct rdpdr_plugin
|
|||||||
wStream* data_in;
|
wStream* data_in;
|
||||||
void* InitHandle;
|
void* InitHandle;
|
||||||
DWORD OpenHandle;
|
DWORD OpenHandle;
|
||||||
wMessagePipe* MsgPipe;
|
wMessageQueue* queue;
|
||||||
|
|
||||||
DEVMAN* devman;
|
DEVMAN* devman;
|
||||||
|
|
||||||
|
@ -105,6 +105,9 @@ void smartcard_context_free(SMARTCARD_CONTEXT* pContext)
|
|||||||
if (!pContext)
|
if (!pContext)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* cancel blocking calls like SCardGetStatusChange */
|
||||||
|
SCardCancel(pContext->hContext);
|
||||||
|
|
||||||
MessageQueue_PostQuit(pContext->IrpQueue, 0);
|
MessageQueue_PostQuit(pContext->IrpQueue, 0);
|
||||||
WaitForSingleObject(pContext->thread, INFINITE);
|
WaitForSingleObject(pContext->thread, INFINITE);
|
||||||
CloseHandle(pContext->thread);
|
CloseHandle(pContext->thread);
|
||||||
@ -118,14 +121,24 @@ static void smartcard_free(DEVICE* device)
|
|||||||
{
|
{
|
||||||
SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) device;
|
SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) device;
|
||||||
|
|
||||||
|
if (smartcard->IrpQueue)
|
||||||
|
{
|
||||||
MessageQueue_PostQuit(smartcard->IrpQueue, 0);
|
MessageQueue_PostQuit(smartcard->IrpQueue, 0);
|
||||||
WaitForSingleObject(smartcard->thread, INFINITE);
|
WaitForSingleObject(smartcard->thread, INFINITE);
|
||||||
|
|
||||||
CloseHandle(smartcard->thread);
|
|
||||||
|
|
||||||
Stream_Free(smartcard->device.data, TRUE);
|
|
||||||
|
|
||||||
MessageQueue_Free(smartcard->IrpQueue);
|
MessageQueue_Free(smartcard->IrpQueue);
|
||||||
|
smartcard->IrpQueue = NULL;
|
||||||
|
|
||||||
|
CloseHandle(smartcard->thread);
|
||||||
|
smartcard->thread = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (smartcard->device.data)
|
||||||
|
{
|
||||||
|
Stream_Free(smartcard->device.data, TRUE);
|
||||||
|
smartcard->device.data = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
ListDictionary_Free(smartcard->rgSCardContextList);
|
ListDictionary_Free(smartcard->rgSCardContextList);
|
||||||
ListDictionary_Free(smartcard->rgOutstandingMessages);
|
ListDictionary_Free(smartcard->rgOutstandingMessages);
|
||||||
Queue_Free(smartcard->CompletedIrpQueue);
|
Queue_Free(smartcard->CompletedIrpQueue);
|
||||||
@ -414,6 +427,7 @@ static void* smartcard_thread_func(void* arg)
|
|||||||
{
|
{
|
||||||
WaitForSingleObject(irp->thread, INFINITE);
|
WaitForSingleObject(irp->thread, INFINITE);
|
||||||
CloseHandle(irp->thread);
|
CloseHandle(irp->thread);
|
||||||
|
irp->thread = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
smartcard_complete_irp(smartcard, irp);
|
smartcard_complete_irp(smartcard, irp);
|
||||||
@ -441,6 +455,7 @@ static void* smartcard_thread_func(void* arg)
|
|||||||
{
|
{
|
||||||
WaitForSingleObject(irp->thread, INFINITE);
|
WaitForSingleObject(irp->thread, INFINITE);
|
||||||
CloseHandle(irp->thread);
|
CloseHandle(irp->thread);
|
||||||
|
irp->thread = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
smartcard_complete_irp(smartcard, irp);
|
smartcard_complete_irp(smartcard, irp);
|
||||||
@ -509,10 +524,16 @@ 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->rgSCardContextList = ListDictionary_New(TRUE);
|
|
||||||
smartcard->rgOutstandingMessages = ListDictionary_New(TRUE);
|
|
||||||
smartcard->CompletedIrpQueue = Queue_New(TRUE, -1, -1);
|
smartcard->CompletedIrpQueue = Queue_New(TRUE, -1, -1);
|
||||||
|
|
||||||
|
smartcard->rgSCardContextList = ListDictionary_New(TRUE);
|
||||||
|
|
||||||
|
ListDictionary_ValueObject(smartcard->rgSCardContextList)->fnObjectFree =
|
||||||
|
(OBJECT_FREE_FN) smartcard_context_free;
|
||||||
|
|
||||||
|
smartcard->rgOutstandingMessages = 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);
|
||||||
|
|
||||||
|
@ -555,8 +555,8 @@ static UINT32 smartcard_ConnectA_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_O
|
|||||||
static UINT32 smartcard_ConnectA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, ConnectA_Call* call)
|
static UINT32 smartcard_ConnectA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, ConnectA_Call* call)
|
||||||
{
|
{
|
||||||
LONG status;
|
LONG status;
|
||||||
SCARDHANDLE hCard;
|
SCARDHANDLE hCard = 0;
|
||||||
Connect_Return ret;
|
Connect_Return ret = { 0 };
|
||||||
IRP* irp = operation->irp;
|
IRP* irp = operation->irp;
|
||||||
|
|
||||||
if ((call->Common.dwPreferredProtocols == SCARD_PROTOCOL_UNDEFINED) &&
|
if ((call->Common.dwPreferredProtocols == SCARD_PROTOCOL_UNDEFINED) &&
|
||||||
@ -604,8 +604,8 @@ static UINT32 smartcard_ConnectW_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_O
|
|||||||
static UINT32 smartcard_ConnectW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, ConnectW_Call* call)
|
static UINT32 smartcard_ConnectW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, ConnectW_Call* call)
|
||||||
{
|
{
|
||||||
LONG status;
|
LONG status;
|
||||||
SCARDHANDLE hCard;
|
SCARDHANDLE hCard = 0;
|
||||||
Connect_Return ret;
|
Connect_Return ret = { 0 };
|
||||||
IRP* irp = operation->irp;
|
IRP* irp = operation->irp;
|
||||||
|
|
||||||
if ((call->Common.dwPreferredProtocols == SCARD_PROTOCOL_UNDEFINED) &&
|
if ((call->Common.dwPreferredProtocols == SCARD_PROTOCOL_UNDEFINED) &&
|
||||||
@ -1020,9 +1020,11 @@ static UINT32 smartcard_GetAttrib_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OP
|
|||||||
if (ret.ReturnCode)
|
if (ret.ReturnCode)
|
||||||
{
|
{
|
||||||
WLog_Print(smartcard->log, WLOG_WARN,
|
WLog_Print(smartcard->log, WLOG_WARN,
|
||||||
"SCardGetAttrib: %s (0x%08X) cbAttrLen: %d\n",
|
"SCardGetAttrib: %s (0x%08X) cbAttrLen: %d",
|
||||||
SCardGetAttributeString(call->dwAttrId), call->dwAttrId, call->cbAttrLen);
|
SCardGetAttributeString(call->dwAttrId), call->dwAttrId, call->cbAttrLen);
|
||||||
Stream_Zero(irp->output, 256);
|
Stream_Zero(irp->output, 256);
|
||||||
|
|
||||||
|
free(ret.pbAttr);
|
||||||
return ret.ReturnCode;
|
return ret.ReturnCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1198,7 +1200,7 @@ UINT32 smartcard_irp_device_control_decode(SMARTCARD_DEVICE* smartcard, SMARTCAR
|
|||||||
if (Stream_Length(irp->input) != (Stream_GetPosition(irp->input) + inputBufferLength))
|
if (Stream_Length(irp->input) != (Stream_GetPosition(irp->input) + inputBufferLength))
|
||||||
{
|
{
|
||||||
WLog_Print(smartcard->log, WLOG_WARN,
|
WLog_Print(smartcard->log, WLOG_WARN,
|
||||||
"InputBufferLength mismatch: Actual: %d Expected: %d\n",
|
"InputBufferLength mismatch: Actual: %d Expected: %d",
|
||||||
Stream_Length(irp->input), Stream_GetPosition(irp->input) + inputBufferLength);
|
Stream_Length(irp->input), Stream_GetPosition(irp->input) + inputBufferLength);
|
||||||
return SCARD_F_INTERNAL_ERROR;
|
return SCARD_F_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
@ -1206,7 +1208,7 @@ UINT32 smartcard_irp_device_control_decode(SMARTCARD_DEVICE* smartcard, SMARTCAR
|
|||||||
WLog_Print(smartcard->log, WLOG_DEBUG, "%s (0x%08X) FileId: %d CompletionId: %d",
|
WLog_Print(smartcard->log, WLOG_DEBUG, "%s (0x%08X) FileId: %d CompletionId: %d",
|
||||||
smartcard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, irp->FileId, irp->CompletionId);
|
smartcard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, irp->FileId, irp->CompletionId);
|
||||||
#if 0
|
#if 0
|
||||||
WLog_DBG(TAG, "%s (0x%08X) FileId: %d CompletionId: %d\n",
|
WLog_DBG(TAG, "%s (0x%08X) FileId: %d CompletionId: %d",
|
||||||
smartcard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, irp->FileId, irp->CompletionId);
|
smartcard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, irp->FileId, irp->CompletionId);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1727,8 +1729,7 @@ UINT32 smartcard_irp_device_control_call(SMARTCARD_DEVICE* smartcard, SMARTCARD_
|
|||||||
(ioControlCode != SCARD_IOCTL_RELEASESTARTEDEVENT))
|
(ioControlCode != SCARD_IOCTL_RELEASESTARTEDEVENT))
|
||||||
{
|
{
|
||||||
offset = (RDPDR_DEVICE_IO_RESPONSE_LENGTH + RDPDR_DEVICE_IO_CONTROL_RSP_HDR_LENGTH);
|
offset = (RDPDR_DEVICE_IO_RESPONSE_LENGTH + RDPDR_DEVICE_IO_CONTROL_RSP_HDR_LENGTH);
|
||||||
smartcard_pack_write_size_align(smartcard, irp->output,
|
smartcard_pack_write_size_align(smartcard, irp->output, Stream_GetPosition(irp->output) - offset, 8);
|
||||||
Stream_GetPosition(irp->output) - offset, 8);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((result != SCARD_S_SUCCESS) && (result != SCARD_E_TIMEOUT) &&
|
if ((result != SCARD_S_SUCCESS) && (result != SCARD_E_TIMEOUT) &&
|
||||||
@ -1756,12 +1757,14 @@ UINT32 smartcard_irp_device_control_call(SMARTCARD_DEVICE* smartcard, SMARTCARD_
|
|||||||
outputBufferLength = Stream_Length(irp->output) - RDPDR_DEVICE_IO_RESPONSE_LENGTH - 4;
|
outputBufferLength = Stream_Length(irp->output) - RDPDR_DEVICE_IO_RESPONSE_LENGTH - 4;
|
||||||
objectBufferLength = outputBufferLength - RDPDR_DEVICE_IO_RESPONSE_LENGTH;
|
objectBufferLength = outputBufferLength - RDPDR_DEVICE_IO_RESPONSE_LENGTH;
|
||||||
Stream_SetPosition(irp->output, RDPDR_DEVICE_IO_RESPONSE_LENGTH);
|
Stream_SetPosition(irp->output, RDPDR_DEVICE_IO_RESPONSE_LENGTH);
|
||||||
|
|
||||||
/* Device Control Response */
|
/* Device Control Response */
|
||||||
Stream_Write_UINT32(irp->output, outputBufferLength); /* OutputBufferLength (4 bytes) */
|
Stream_Write_UINT32(irp->output, outputBufferLength); /* OutputBufferLength (4 bytes) */
|
||||||
smartcard_pack_common_type_header(smartcard, irp->output); /* CommonTypeHeader (8 bytes) */
|
smartcard_pack_common_type_header(smartcard, irp->output); /* CommonTypeHeader (8 bytes) */
|
||||||
smartcard_pack_private_type_header(smartcard, irp->output, objectBufferLength); /* PrivateTypeHeader (8 bytes) */
|
smartcard_pack_private_type_header(smartcard, irp->output, objectBufferLength); /* PrivateTypeHeader (8 bytes) */
|
||||||
Stream_Write_UINT32(irp->output, result); /* Result (4 bytes) */
|
Stream_Write_UINT32(irp->output, result); /* Result (4 bytes) */
|
||||||
Stream_SetPosition(irp->output, Stream_Length(irp->output));
|
Stream_SetPosition(irp->output, Stream_Length(irp->output));
|
||||||
|
|
||||||
return SCARD_S_SUCCESS;
|
return SCARD_S_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,16 @@
|
|||||||
fun:getaddrinfo
|
fun:getaddrinfo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
ignore pcsc-lite SCardConnect
|
||||||
|
Memcheck:Param
|
||||||
|
socketcall.sendto(msg)
|
||||||
|
fun:send
|
||||||
|
fun:MessageSend
|
||||||
|
fun:MessageSendWithHeader
|
||||||
|
fun:SCardConnect
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
ignore openssl malloc
|
ignore openssl malloc
|
||||||
Memcheck:Leak
|
Memcheck:Leak
|
||||||
|
@ -200,6 +200,7 @@ BOOL rdp_recv_server_redirection_pdu(rdpRdp* rdp, wStream* s)
|
|||||||
Stream_Read_UINT16(s, length); /* length (2 bytes) */
|
Stream_Read_UINT16(s, length); /* length (2 bytes) */
|
||||||
Stream_Read_UINT32(s, redirection->sessionID); /* sessionID (4 bytes) */
|
Stream_Read_UINT32(s, redirection->sessionID); /* sessionID (4 bytes) */
|
||||||
Stream_Read_UINT32(s, redirection->flags); /* redirFlags (4 bytes) */
|
Stream_Read_UINT32(s, redirection->flags); /* redirFlags (4 bytes) */
|
||||||
|
|
||||||
WLog_Print(redirection->log, WLOG_DEBUG, "flags: 0x%04X, redirFlags: 0x%04X length: %d, sessionID: 0x%08X",
|
WLog_Print(redirection->log, WLOG_DEBUG, "flags: 0x%04X, redirFlags: 0x%04X length: %d, sessionID: 0x%08X",
|
||||||
flags, redirection->flags, length, redirection->sessionID);
|
flags, redirection->flags, length, redirection->sessionID);
|
||||||
#ifdef WITH_DEBUG_REDIR
|
#ifdef WITH_DEBUG_REDIR
|
||||||
|
@ -1410,6 +1410,9 @@ WINSCARDAPI LONG WINAPI PCSC_SCardGetStatusChange_Internal(SCARDCONTEXT hContext
|
|||||||
if (!cReaders)
|
if (!cReaders)
|
||||||
return SCARD_S_SUCCESS;
|
return SCARD_S_SUCCESS;
|
||||||
|
|
||||||
|
/* pcsc-lite interprets value 0 as INFINITE, work around the problem by using value 1 */
|
||||||
|
pcsc_dwTimeout = pcsc_dwTimeout ? pcsc_dwTimeout : 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apple's SmartCard Services (not vanilla pcsc-lite) appears to have trouble with the
|
* Apple's SmartCard Services (not vanilla pcsc-lite) appears to have trouble with the
|
||||||
* "\\\\?PnP?\\Notification" reader name. I am always getting EXC_BAD_ACCESS with it.
|
* "\\\\?PnP?\\Notification" reader name. I am always getting EXC_BAD_ACCESS with it.
|
||||||
@ -1463,15 +1466,10 @@ WINSCARDAPI LONG WINAPI PCSC_SCardGetStatusChange_Internal(SCARDCONTEXT hContext
|
|||||||
|
|
||||||
cMappedReaders = j;
|
cMappedReaders = j;
|
||||||
|
|
||||||
/**
|
|
||||||
* pcsc-lite interprets dwTimeout value 0 as INFINITE, use value 1 as a workaround
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (cMappedReaders > 0)
|
if (cMappedReaders > 0)
|
||||||
{
|
{
|
||||||
status = (LONG) g_PCSC.pfnSCardGetStatusChange(hContext,
|
status = (LONG) g_PCSC.pfnSCardGetStatusChange(hContext,
|
||||||
pcsc_dwTimeout ? pcsc_dwTimeout : 1,
|
pcsc_dwTimeout, states, cMappedReaders);
|
||||||
states, cMappedReaders);
|
|
||||||
status = PCSC_MapErrorCodeToWinSCard(status);
|
status = PCSC_MapErrorCodeToWinSCard(status);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2244,21 +2242,18 @@ WINSCARDAPI LONG WINAPI PCSC_SCardGetAttrib_FriendlyName(SCARDHANDLE hCard, DWOR
|
|||||||
|
|
||||||
cbAttrLen = *pcbAttrLen;
|
cbAttrLen = *pcbAttrLen;
|
||||||
*pcbAttrLen = SCARD_AUTOALLOCATE;
|
*pcbAttrLen = SCARD_AUTOALLOCATE;
|
||||||
status = PCSC_SCardGetAttrib_Internal(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME_A,
|
status = PCSC_SCardGetAttrib_Internal(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME_A, (LPBYTE) &pbAttrA, pcbAttrLen);
|
||||||
(LPBYTE) &pbAttrA, pcbAttrLen);
|
|
||||||
|
|
||||||
if (status != SCARD_S_SUCCESS)
|
if (status != SCARD_S_SUCCESS)
|
||||||
{
|
{
|
||||||
pbAttrA = NULL;
|
pbAttrA = NULL;
|
||||||
*pcbAttrLen = SCARD_AUTOALLOCATE;
|
*pcbAttrLen = SCARD_AUTOALLOCATE;
|
||||||
status = PCSC_SCardGetAttrib_Internal(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME_W,
|
status = PCSC_SCardGetAttrib_Internal(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME_W, (LPBYTE) &pbAttrW, pcbAttrLen);
|
||||||
(LPBYTE) &pbAttrW, pcbAttrLen);
|
|
||||||
|
|
||||||
if (status != SCARD_S_SUCCESS)
|
if (status != SCARD_S_SUCCESS)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
length = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) pbAttrW,
|
length = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) pbAttrW, *pcbAttrLen, (char**) &pbAttrA, 0, NULL, NULL);
|
||||||
*pcbAttrLen, (char**) &pbAttrA, 0, NULL, NULL);
|
|
||||||
namePCSC = pbAttrA;
|
namePCSC = pbAttrA;
|
||||||
PCSC_SCardFreeMemory_Internal(hContext, pbAttrW);
|
PCSC_SCardFreeMemory_Internal(hContext, pbAttrW);
|
||||||
}
|
}
|
||||||
@ -2290,6 +2285,7 @@ WINSCARDAPI LONG WINAPI PCSC_SCardGetAttrib_FriendlyName(SCARDHANDLE hCard, DWOR
|
|||||||
|
|
||||||
if (dwAttrId == SCARD_ATTR_DEVICE_FRIENDLY_NAME_W)
|
if (dwAttrId == SCARD_ATTR_DEVICE_FRIENDLY_NAME_W)
|
||||||
{
|
{
|
||||||
|
/* length here includes null terminator */
|
||||||
length = ConvertToUnicode(CP_UTF8, 0, (char*) friendlyNameA, -1, &friendlyNameW, 0);
|
length = ConvertToUnicode(CP_UTF8, 0, (char*) friendlyNameA, -1, &friendlyNameW, 0);
|
||||||
free(friendlyNameA);
|
free(friendlyNameA);
|
||||||
|
|
||||||
@ -2304,14 +2300,14 @@ WINSCARDAPI LONG WINAPI PCSC_SCardGetAttrib_FriendlyName(SCARDHANDLE hCard, DWOR
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (((length + 1) * 2) > cbAttrLen)
|
if ((length * 2) > cbAttrLen)
|
||||||
{
|
{
|
||||||
free(friendlyNameW);
|
free(friendlyNameW);
|
||||||
return SCARD_E_INSUFFICIENT_BUFFER;
|
return SCARD_E_INSUFFICIENT_BUFFER;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CopyMemory(pbAttr, (BYTE*) friendlyNameW, ((length + 1) * 2));
|
CopyMemory(pbAttr, (BYTE*) friendlyNameW, (length * 2));
|
||||||
*pcbAttrLen = length * 2;
|
*pcbAttrLen = length * 2;
|
||||||
free(friendlyNameW);
|
free(friendlyNameW);
|
||||||
}
|
}
|
||||||
@ -2341,6 +2337,8 @@ WINSCARDAPI LONG WINAPI PCSC_SCardGetAttrib_FriendlyName(SCARDHANDLE hCard, DWOR
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(namePCSC);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user