Added multi filter for smartcard. (based on #4837 by @informatimago)
This commit is contained in:
parent
8740219118
commit
b2ce309b28
@ -34,6 +34,29 @@
|
|||||||
|
|
||||||
#include "smartcard_main.h"
|
#include "smartcard_main.h"
|
||||||
|
|
||||||
|
#define CAST_FROM_DEVICE(device) cast_device_from(device, __FUNCTION__, __FILE__, __LINE__)
|
||||||
|
|
||||||
|
static SMARTCARD_DEVICE* sSmartcard = NULL;
|
||||||
|
|
||||||
|
static SMARTCARD_DEVICE* cast_device_from(DEVICE* device, const char* fkt, const char* file,
|
||||||
|
int line)
|
||||||
|
{
|
||||||
|
if (!device)
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "%s [%s:%d] Called smartcard channel with NULL device", fkt, file, line);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device->type != RDPDR_DTYP_SMARTCARD)
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "%s [%s:%d] Called smartcard channel with invalid device of type %"PRIx32,
|
||||||
|
fkt, file, line, device->type);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (SMARTCARD_DEVICE*)device;
|
||||||
|
}
|
||||||
|
|
||||||
static DWORD WINAPI smartcard_context_thread(LPVOID arg)
|
static DWORD WINAPI smartcard_context_thread(LPVOID arg)
|
||||||
{
|
{
|
||||||
SMARTCARD_CONTEXT* pContext = (SMARTCARD_CONTEXT*)arg;
|
SMARTCARD_CONTEXT* pContext = (SMARTCARD_CONTEXT*)arg;
|
||||||
@ -152,8 +175,10 @@ error_irpqueue:
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void smartcard_context_free(SMARTCARD_CONTEXT* pContext)
|
void smartcard_context_free(void* pCtx)
|
||||||
{
|
{
|
||||||
|
SMARTCARD_CONTEXT* pContext = pCtx;
|
||||||
|
|
||||||
if (!pContext)
|
if (!pContext)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -169,7 +194,6 @@ void smartcard_context_free(SMARTCARD_CONTEXT* pContext)
|
|||||||
free(pContext);
|
free(pContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void smartcard_release_all_contexts(SMARTCARD_DEVICE* smartcard)
|
static void smartcard_release_all_contexts(SMARTCARD_DEVICE* smartcard)
|
||||||
{
|
{
|
||||||
int index;
|
int index;
|
||||||
@ -249,7 +273,29 @@ static void smartcard_release_all_contexts(SMARTCARD_DEVICE* smartcard)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static UINT smartcard_free_(SMARTCARD_DEVICE* smartcard)
|
||||||
|
{
|
||||||
|
if (!smartcard)
|
||||||
|
return CHANNEL_RC_OK;
|
||||||
|
|
||||||
|
if (smartcard->IrpQueue)
|
||||||
|
{
|
||||||
|
MessageQueue_Free(smartcard->IrpQueue);
|
||||||
|
CloseHandle(smartcard->thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream_Free(smartcard->device.data, TRUE);
|
||||||
|
LinkedList_Free(smartcard->names);
|
||||||
|
ListDictionary_Free(smartcard->rgSCardContextList);
|
||||||
|
ListDictionary_Free(smartcard->rgOutstandingMessages);
|
||||||
|
Queue_Free(smartcard->CompletedIrpQueue);
|
||||||
|
|
||||||
|
if (smartcard->StartedEvent)
|
||||||
|
SCardReleaseStartedEvent();
|
||||||
|
|
||||||
|
free(smartcard);
|
||||||
|
return CHANNEL_RC_OK;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Function description
|
* Function description
|
||||||
*
|
*
|
||||||
@ -258,7 +304,11 @@ static void smartcard_release_all_contexts(SMARTCARD_DEVICE* smartcard)
|
|||||||
static UINT smartcard_free(DEVICE* device)
|
static UINT smartcard_free(DEVICE* device)
|
||||||
{
|
{
|
||||||
UINT error;
|
UINT error;
|
||||||
SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) device;
|
SMARTCARD_DEVICE* smartcard = CAST_FROM_DEVICE(device);
|
||||||
|
|
||||||
|
if (!smartcard)
|
||||||
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calling smartcard_release_all_contexts to unblock all operations waiting for transactions
|
* Calling smartcard_release_all_contexts to unblock all operations waiting for transactions
|
||||||
* to unlock.
|
* to unlock.
|
||||||
@ -276,31 +326,12 @@ static UINT smartcard_free(DEVICE* device)
|
|||||||
WLog_ERR(TAG, "WaitForSingleObject failed with error %"PRIu32"!", error);
|
WLog_ERR(TAG, "WaitForSingleObject failed with error %"PRIu32"!", error);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageQueue_Free(smartcard->IrpQueue);
|
|
||||||
smartcard->IrpQueue = NULL;
|
|
||||||
CloseHandle(smartcard->thread);
|
|
||||||
smartcard->thread = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (smartcard->device.data)
|
if (sSmartcard == smartcard)
|
||||||
{
|
sSmartcard = NULL;
|
||||||
Stream_Free(smartcard->device.data, TRUE);
|
|
||||||
smartcard->device.data = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ListDictionary_Free(smartcard->rgSCardContextList);
|
return smartcard_free_(smartcard);
|
||||||
ListDictionary_Free(smartcard->rgOutstandingMessages);
|
|
||||||
Queue_Free(smartcard->CompletedIrpQueue);
|
|
||||||
|
|
||||||
if (smartcard->StartedEvent)
|
|
||||||
{
|
|
||||||
SCardReleaseStartedEvent();
|
|
||||||
smartcard->StartedEvent = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(device);
|
|
||||||
return CHANNEL_RC_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -315,7 +346,11 @@ static UINT smartcard_free(DEVICE* device)
|
|||||||
*/
|
*/
|
||||||
static UINT smartcard_init(DEVICE* device)
|
static UINT smartcard_init(DEVICE* device)
|
||||||
{
|
{
|
||||||
SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) device;
|
SMARTCARD_DEVICE* smartcard = CAST_FROM_DEVICE(device);
|
||||||
|
|
||||||
|
if (!smartcard)
|
||||||
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
|
||||||
smartcard_release_all_contexts(smartcard);
|
smartcard_release_all_contexts(smartcard);
|
||||||
return CHANNEL_RC_OK;
|
return CHANNEL_RC_OK;
|
||||||
}
|
}
|
||||||
@ -325,7 +360,7 @@ static UINT smartcard_init(DEVICE* device)
|
|||||||
*
|
*
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
UINT smartcard_complete_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
|
static UINT smartcard_complete_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
|
||||||
{
|
{
|
||||||
void* key;
|
void* key;
|
||||||
key = (void*)(size_t) irp->CompletionId;
|
key = (void*)(size_t) irp->CompletionId;
|
||||||
@ -343,7 +378,7 @@ UINT smartcard_complete_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
|
|||||||
*
|
*
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
UINT smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
|
static UINT smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
|
||||||
{
|
{
|
||||||
void* key;
|
void* key;
|
||||||
LONG status;
|
LONG status;
|
||||||
@ -505,8 +540,12 @@ static DWORD WINAPI smartcard_thread_func(LPVOID arg)
|
|||||||
DWORD status;
|
DWORD status;
|
||||||
HANDLE hEvents[2];
|
HANDLE hEvents[2];
|
||||||
wMessage message;
|
wMessage message;
|
||||||
SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) arg;
|
|
||||||
UINT error = CHANNEL_RC_OK;
|
UINT error = CHANNEL_RC_OK;
|
||||||
|
SMARTCARD_DEVICE* smartcard = CAST_FROM_DEVICE(arg);
|
||||||
|
|
||||||
|
if (!smartcard)
|
||||||
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
|
||||||
nCount = 0;
|
nCount = 0;
|
||||||
hEvents[nCount++] = MessageQueue_Event(smartcard->IrpQueue);
|
hEvents[nCount++] = MessageQueue_Event(smartcard->IrpQueue);
|
||||||
hEvents[nCount++] = Queue_Event(smartcard->CompletedIrpQueue);
|
hEvents[nCount++] = Queue_Event(smartcard->CompletedIrpQueue);
|
||||||
@ -660,7 +699,10 @@ out:
|
|||||||
*/
|
*/
|
||||||
static UINT smartcard_irp_request(DEVICE* device, IRP* irp)
|
static UINT smartcard_irp_request(DEVICE* device, IRP* irp)
|
||||||
{
|
{
|
||||||
SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) device;
|
SMARTCARD_DEVICE* smartcard = CAST_FROM_DEVICE(device);
|
||||||
|
|
||||||
|
if (!smartcard)
|
||||||
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
|
||||||
if (!MessageQueue_Post(smartcard->IrpQueue, NULL, 0, (void*) irp, NULL))
|
if (!MessageQueue_Post(smartcard->IrpQueue, NULL, 0, (void*) irp, NULL))
|
||||||
{
|
{
|
||||||
@ -681,99 +723,99 @@ static UINT smartcard_irp_request(DEVICE* device, IRP* irp)
|
|||||||
*/
|
*/
|
||||||
UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
|
UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
|
||||||
{
|
{
|
||||||
|
SMARTCARD_DEVICE* smartcard = NULL;
|
||||||
size_t length;
|
size_t length;
|
||||||
SMARTCARD_DEVICE* smartcard;
|
|
||||||
UINT error = CHANNEL_RC_NO_MEMORY;
|
UINT error = CHANNEL_RC_NO_MEMORY;
|
||||||
smartcard = (SMARTCARD_DEVICE*) calloc(1, sizeof(SMARTCARD_DEVICE));
|
|
||||||
|
|
||||||
if (!smartcard)
|
if (!sSmartcard)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "calloc failed!");
|
wObject* obj;
|
||||||
return CHANNEL_RC_NO_MEMORY;
|
smartcard = (SMARTCARD_DEVICE*) calloc(1, sizeof(SMARTCARD_DEVICE));
|
||||||
|
|
||||||
|
if (!smartcard)
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "calloc failed!");
|
||||||
|
return CHANNEL_RC_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
smartcard->device.type = RDPDR_DTYP_SMARTCARD;
|
||||||
|
smartcard->device.name = "SCARD";
|
||||||
|
smartcard->device.IRPRequest = smartcard_irp_request;
|
||||||
|
smartcard->device.Init = smartcard_init;
|
||||||
|
smartcard->device.Free = smartcard_free;
|
||||||
|
smartcard->names = LinkedList_New();
|
||||||
|
smartcard->rdpcontext = pEntryPoints->rdpcontext;
|
||||||
|
length = strlen(smartcard->device.name);
|
||||||
|
smartcard->device.data = Stream_New(NULL, length + 1);
|
||||||
|
|
||||||
|
if (!smartcard->device.data || !smartcard->names)
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "Stream_New failed!");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream_Write(smartcard->device.data, "SCARD", 6);
|
||||||
|
smartcard->IrpQueue = MessageQueue_New(NULL);
|
||||||
|
|
||||||
|
if (!smartcard->IrpQueue)
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "MessageQueue_New failed!");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
smartcard->CompletedIrpQueue = Queue_New(TRUE, -1, -1);
|
||||||
|
|
||||||
|
if (!smartcard->CompletedIrpQueue)
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "Queue_New failed!");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
smartcard->rgSCardContextList = ListDictionary_New(TRUE);
|
||||||
|
|
||||||
|
if (!smartcard->rgSCardContextList)
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "ListDictionary_New failed!");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
obj = ListDictionary_ValueObject(smartcard->rgSCardContextList);
|
||||||
|
obj->fnObjectFree = smartcard_context_free;
|
||||||
|
smartcard->rgOutstandingMessages = ListDictionary_New(TRUE);
|
||||||
|
|
||||||
|
if (!smartcard->rgOutstandingMessages)
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "ListDictionary_New failed!");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((error = pEntryPoints->RegisterDevice(pEntryPoints->devman, &smartcard->device)))
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "RegisterDevice failed!");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
smartcard->thread = CreateThread(NULL, 0,
|
||||||
|
smartcard_thread_func,
|
||||||
|
smartcard, CREATE_SUSPENDED, NULL);
|
||||||
|
|
||||||
|
if (!smartcard->thread)
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "ListDictionary_New failed!");
|
||||||
|
error = ERROR_INTERNAL_ERROR;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResumeThread(smartcard->thread);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
smartcard = sSmartcard;
|
||||||
|
|
||||||
smartcard->device.type = RDPDR_DTYP_SMARTCARD;
|
LinkedList_AddLast(smartcard->names, pEntryPoints->device->Name);
|
||||||
smartcard->device.name = "SCARD";
|
sSmartcard = smartcard;
|
||||||
smartcard->device.IRPRequest = smartcard_irp_request;
|
|
||||||
smartcard->device.Init = smartcard_init;
|
|
||||||
smartcard->device.Free = smartcard_free;
|
|
||||||
smartcard->rdpcontext = pEntryPoints->rdpcontext;
|
|
||||||
length = strlen(smartcard->device.name);
|
|
||||||
smartcard->device.data = Stream_New(NULL, length + 1);
|
|
||||||
|
|
||||||
if (!smartcard->device.data)
|
|
||||||
{
|
|
||||||
WLog_ERR(TAG, "Stream_New failed!");
|
|
||||||
goto error_device_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
Stream_Write(smartcard->device.data, "SCARD", 6);
|
|
||||||
smartcard->IrpQueue = MessageQueue_New(NULL);
|
|
||||||
|
|
||||||
if (!smartcard->IrpQueue)
|
|
||||||
{
|
|
||||||
WLog_ERR(TAG, "MessageQueue_New failed!");
|
|
||||||
goto error_irp_queue;
|
|
||||||
}
|
|
||||||
|
|
||||||
smartcard->CompletedIrpQueue = Queue_New(TRUE, -1, -1);
|
|
||||||
|
|
||||||
if (!smartcard->CompletedIrpQueue)
|
|
||||||
{
|
|
||||||
WLog_ERR(TAG, "Queue_New failed!");
|
|
||||||
goto error_completed_irp_queue;
|
|
||||||
}
|
|
||||||
|
|
||||||
smartcard->rgSCardContextList = ListDictionary_New(TRUE);
|
|
||||||
|
|
||||||
if (!smartcard->rgSCardContextList)
|
|
||||||
{
|
|
||||||
WLog_ERR(TAG, "ListDictionary_New failed!");
|
|
||||||
goto error_context_list;
|
|
||||||
}
|
|
||||||
|
|
||||||
ListDictionary_ValueObject(smartcard->rgSCardContextList)->fnObjectFree =
|
|
||||||
(OBJECT_FREE_FN) smartcard_context_free;
|
|
||||||
smartcard->rgOutstandingMessages = ListDictionary_New(TRUE);
|
|
||||||
|
|
||||||
if (!smartcard->rgOutstandingMessages)
|
|
||||||
{
|
|
||||||
WLog_ERR(TAG, "ListDictionary_New failed!");
|
|
||||||
goto error_outstanding_messages;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((error = pEntryPoints->RegisterDevice(pEntryPoints->devman,
|
|
||||||
(DEVICE*) smartcard)))
|
|
||||||
{
|
|
||||||
WLog_ERR(TAG, "RegisterDevice failed!");
|
|
||||||
goto error_outstanding_messages;
|
|
||||||
}
|
|
||||||
|
|
||||||
smartcard->thread = CreateThread(NULL, 0,
|
|
||||||
smartcard_thread_func,
|
|
||||||
smartcard, CREATE_SUSPENDED, NULL);
|
|
||||||
|
|
||||||
if (!smartcard->thread)
|
|
||||||
{
|
|
||||||
WLog_ERR(TAG, "ListDictionary_New failed!");
|
|
||||||
error = ERROR_INTERNAL_ERROR;
|
|
||||||
goto error_thread;
|
|
||||||
}
|
|
||||||
|
|
||||||
ResumeThread(smartcard->thread);
|
|
||||||
return CHANNEL_RC_OK;
|
return CHANNEL_RC_OK;
|
||||||
error_thread:
|
fail:
|
||||||
ListDictionary_Free(smartcard->rgOutstandingMessages);
|
smartcard_free_(smartcard);
|
||||||
error_outstanding_messages:
|
|
||||||
ListDictionary_Free(smartcard->rgSCardContextList);
|
|
||||||
error_context_list:
|
|
||||||
Queue_Free(smartcard->CompletedIrpQueue);
|
|
||||||
error_completed_irp_queue:
|
|
||||||
MessageQueue_Free(smartcard->IrpQueue);
|
|
||||||
error_irp_queue:
|
|
||||||
Stream_Free(smartcard->device.data, TRUE);
|
|
||||||
error_device_data:
|
|
||||||
free(smartcard);
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,15 +117,14 @@ struct _SMARTCARD_DEVICE
|
|||||||
wListDictionary* rgSCardContextList;
|
wListDictionary* rgSCardContextList;
|
||||||
wListDictionary* rgOutstandingMessages;
|
wListDictionary* rgOutstandingMessages;
|
||||||
rdpContext* rdpcontext;
|
rdpContext* rdpcontext;
|
||||||
|
wLinkedList* names;
|
||||||
};
|
};
|
||||||
|
|
||||||
SMARTCARD_CONTEXT* smartcard_context_new(SMARTCARD_DEVICE* smartcard, SCARDCONTEXT hContext);
|
SMARTCARD_CONTEXT* smartcard_context_new(SMARTCARD_DEVICE* smartcard, SCARDCONTEXT hContext);
|
||||||
void smartcard_context_free(SMARTCARD_CONTEXT* pContext);
|
void smartcard_context_free(void* pContext);
|
||||||
|
|
||||||
UINT smartcard_complete_irp(SMARTCARD_DEVICE* smartcard, IRP* irp);
|
LONG smartcard_irp_device_control_decode(SMARTCARD_DEVICE* smartcard,
|
||||||
UINT smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp);
|
SMARTCARD_OPERATION* operation);
|
||||||
|
|
||||||
LONG smartcard_irp_device_control_decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation);
|
|
||||||
LONG smartcard_irp_device_control_call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation);
|
LONG smartcard_irp_device_control_call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation);
|
||||||
|
|
||||||
#include "smartcard_pack.h"
|
#include "smartcard_pack.h"
|
||||||
|
@ -432,6 +432,84 @@ static LONG smartcard_ListReaderGroupsW_Call(SMARTCARD_DEVICE* smartcard,
|
|||||||
return ret.ReturnCode;
|
return ret.ReturnCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL filter_match(wLinkedList* list, LPCSTR reader, size_t readerLen)
|
||||||
|
{
|
||||||
|
if (readerLen < 1)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
LinkedList_Enumerator_Reset(list);
|
||||||
|
|
||||||
|
while (LinkedList_Enumerator_MoveNext(list))
|
||||||
|
{
|
||||||
|
const char* filter = LinkedList_Enumerator_Current(list);
|
||||||
|
|
||||||
|
if (filter)
|
||||||
|
{
|
||||||
|
if (strstr(reader, filter) != NULL)
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DWORD filter_device_by_name_a(wLinkedList* list, LPSTR* mszReaders, DWORD cchReaders)
|
||||||
|
{
|
||||||
|
size_t rpos = 0, wpos = 0;
|
||||||
|
|
||||||
|
if (LinkedList_Count(list) < 1)
|
||||||
|
return cchReaders;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
LPCSTR rreader = &(*mszReaders)[rpos];
|
||||||
|
LPSTR wreader = &(*mszReaders)[wpos];
|
||||||
|
size_t readerLen = strnlen(rreader, cchReaders - rpos);
|
||||||
|
rpos += readerLen + 1;
|
||||||
|
|
||||||
|
if (filter_match(list, rreader, readerLen))
|
||||||
|
{
|
||||||
|
if (rreader != wreader)
|
||||||
|
memmove(wreader, rreader, readerLen);
|
||||||
|
|
||||||
|
wpos += readerLen + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (rpos < cchReaders);
|
||||||
|
|
||||||
|
/* this string must be double 0 terminated */
|
||||||
|
if (rpos != wpos)
|
||||||
|
{
|
||||||
|
if (wpos >= cchReaders)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
(*mszReaders)[wpos++] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
return wpos;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DWORD filter_device_by_name_w(wLinkedList* list, LPWSTR* mszReaders, DWORD cchReaders)
|
||||||
|
{
|
||||||
|
DWORD rc;
|
||||||
|
LPSTR readers;
|
||||||
|
|
||||||
|
if (LinkedList_Count(list) < 1)
|
||||||
|
return cchReaders;
|
||||||
|
|
||||||
|
if (ConvertFromUnicode(CP_UTF8, 0, *mszReaders, cchReaders, &readers, 0, NULL, NULL) != cchReaders)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
free(*mszReaders);
|
||||||
|
rc = filter_device_by_name_a(list, &readers, cchReaders);
|
||||||
|
|
||||||
|
if (ConvertToUnicode(CP_UTF8, 0, &readers, rc, mszReaders, 0) != rc)
|
||||||
|
rc = 0;
|
||||||
|
|
||||||
|
free(readers);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
static LONG smartcard_ListReadersA_Decode(SMARTCARD_DEVICE* smartcard,
|
static LONG smartcard_ListReadersA_Decode(SMARTCARD_DEVICE* smartcard,
|
||||||
SMARTCARD_OPERATION* operation)
|
SMARTCARD_OPERATION* operation)
|
||||||
{
|
{
|
||||||
@ -462,6 +540,7 @@ static LONG smartcard_ListReadersA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_O
|
|||||||
cchReaders = SCARD_AUTOALLOCATE;
|
cchReaders = SCARD_AUTOALLOCATE;
|
||||||
status = ret.ReturnCode = SCardListReadersA(operation->hContext, (LPCSTR) call->mszGroups,
|
status = ret.ReturnCode = SCardListReadersA(operation->hContext, (LPCSTR) call->mszGroups,
|
||||||
(LPSTR) &mszReaders, &cchReaders);
|
(LPSTR) &mszReaders, &cchReaders);
|
||||||
|
cchReaders = filter_device_by_name_a(smartcard->names, &mszReaders, cchReaders);
|
||||||
ret.msz = (BYTE*) mszReaders;
|
ret.msz = (BYTE*) mszReaders;
|
||||||
ret.cBytes = cchReaders;
|
ret.cBytes = cchReaders;
|
||||||
|
|
||||||
@ -524,6 +603,7 @@ static LONG smartcard_ListReadersW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_O
|
|||||||
cchReaders = SCARD_AUTOALLOCATE;
|
cchReaders = SCARD_AUTOALLOCATE;
|
||||||
status = ret.ReturnCode = SCardListReadersW(operation->hContext,
|
status = ret.ReturnCode = SCardListReadersW(operation->hContext,
|
||||||
(LPCWSTR) call->mszGroups, (LPWSTR) &mszReaders, &cchReaders);
|
(LPCWSTR) call->mszGroups, (LPWSTR) &mszReaders, &cchReaders);
|
||||||
|
cchReaders = filter_device_by_name_w(smartcard->names, &mszReaders, cchReaders);
|
||||||
ret.msz = (BYTE*) mszReaders;
|
ret.msz = (BYTE*) mszReaders;
|
||||||
ret.cBytes = cchReaders * 2;
|
ret.cBytes = cchReaders * 2;
|
||||||
|
|
||||||
@ -1053,7 +1133,6 @@ static LONG smartcard_StatusA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERAT
|
|||||||
IRP* irp = operation->irp;
|
IRP* irp = operation->irp;
|
||||||
Status_Call* call = operation->call;
|
Status_Call* call = operation->call;
|
||||||
ZeroMemory(ret.pbAtr, 32);
|
ZeroMemory(ret.pbAtr, 32);
|
||||||
|
|
||||||
call->cbAtrLen = 32;
|
call->cbAtrLen = 32;
|
||||||
cbAtrLen = call->cbAtrLen;
|
cbAtrLen = call->cbAtrLen;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user