Merge pull request #4312 from bmiklautz/smartcard-cleanup
Smartcard fixes and cleanup
This commit is contained in:
commit
097f8edd97
@ -385,17 +385,17 @@ UINT smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
|
||||
|
||||
asyncIrp = TRUE;
|
||||
|
||||
/**
|
||||
* The following matches mstsc's behavior of processing
|
||||
* only certain requests asynchronously while processing
|
||||
* those expected to return fast synchronously.
|
||||
*/
|
||||
|
||||
switch (operation->ioControlCode)
|
||||
{
|
||||
case SCARD_IOCTL_ESTABLISHCONTEXT:
|
||||
case SCARD_IOCTL_RELEASECONTEXT:
|
||||
case SCARD_IOCTL_ISVALIDCONTEXT:
|
||||
case SCARD_IOCTL_CANCEL:
|
||||
case SCARD_IOCTL_ACCESSSTARTEDEVENT:
|
||||
case SCARD_IOCTL_RELEASESTARTEDEVENT:
|
||||
asyncIrp = FALSE;
|
||||
break;
|
||||
|
||||
case SCARD_IOCTL_LISTREADERGROUPSA:
|
||||
case SCARD_IOCTL_LISTREADERGROUPSW:
|
||||
case SCARD_IOCTL_LISTREADERSA:
|
||||
@ -416,21 +416,14 @@ UINT smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
|
||||
case SCARD_IOCTL_LOCATECARDSW:
|
||||
case SCARD_IOCTL_LOCATECARDSBYATRA:
|
||||
case SCARD_IOCTL_LOCATECARDSBYATRW:
|
||||
case SCARD_IOCTL_CANCEL:
|
||||
case SCARD_IOCTL_READCACHEA:
|
||||
case SCARD_IOCTL_READCACHEW:
|
||||
case SCARD_IOCTL_WRITECACHEA:
|
||||
case SCARD_IOCTL_WRITECACHEW:
|
||||
case SCARD_IOCTL_GETREADERICON:
|
||||
case SCARD_IOCTL_GETDEVICETYPEID:
|
||||
asyncIrp = FALSE;
|
||||
break;
|
||||
|
||||
case SCARD_IOCTL_GETSTATUSCHANGEA:
|
||||
case SCARD_IOCTL_GETSTATUSCHANGEW:
|
||||
asyncIrp = TRUE;
|
||||
break;
|
||||
|
||||
case SCARD_IOCTL_CONNECTA:
|
||||
case SCARD_IOCTL_CONNECTW:
|
||||
case SCARD_IOCTL_RECONNECT:
|
||||
@ -447,11 +440,6 @@ UINT smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
|
||||
case SCARD_IOCTL_GETTRANSMITCOUNT:
|
||||
asyncIrp = TRUE;
|
||||
break;
|
||||
|
||||
case SCARD_IOCTL_ACCESSSTARTEDEVENT:
|
||||
case SCARD_IOCTL_RELEASESTARTEDEVENT:
|
||||
asyncIrp = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
pContext = ListDictionary_GetItemValue(smartcard->rgSCardContextList,
|
||||
@ -689,17 +677,11 @@ static UINT smartcard_irp_request(DEVICE* device, IRP* irp)
|
||||
*/
|
||||
UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
|
||||
{
|
||||
char* name;
|
||||
char* path;
|
||||
size_t length;
|
||||
int ck;
|
||||
RDPDR_SMARTCARD* device;
|
||||
SMARTCARD_DEVICE* smartcard;
|
||||
LONG status;
|
||||
UINT error = CHANNEL_RC_NO_MEMORY;
|
||||
device = (RDPDR_SMARTCARD*) pEntryPoints->device;
|
||||
name = device->Name;
|
||||
path = device->Path;
|
||||
smartcard = (SMARTCARD_DEVICE*) calloc(1, sizeof(SMARTCARD_DEVICE));
|
||||
|
||||
if (!smartcard)
|
||||
@ -724,29 +706,6 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
|
||||
}
|
||||
|
||||
Stream_Write(smartcard->device.data, "SCARD", 6);
|
||||
smartcard->name = NULL;
|
||||
smartcard->path = NULL;
|
||||
|
||||
if (path)
|
||||
{
|
||||
smartcard->path = path;
|
||||
smartcard->name = name;
|
||||
}
|
||||
else if (name)
|
||||
{
|
||||
if (1 == sscanf(name, "%d", &ck))
|
||||
smartcard->path = name;
|
||||
else
|
||||
smartcard->name = name;
|
||||
}
|
||||
|
||||
status = SCardAddReaderName(&smartcard->thread, (LPSTR) name);
|
||||
|
||||
if (status != SCARD_S_SUCCESS)
|
||||
{
|
||||
WLog_ERR(TAG, "Failed to add reader name!");
|
||||
goto error_device_data;
|
||||
}
|
||||
|
||||
smartcard->IrpQueue = MessageQueue_New(NULL);
|
||||
|
||||
|
@ -110,9 +110,6 @@ struct _SMARTCARD_DEVICE
|
||||
{
|
||||
DEVICE device;
|
||||
|
||||
char* name;
|
||||
char* path;
|
||||
|
||||
HANDLE thread;
|
||||
HANDLE StartedEvent;
|
||||
wMessageQueue* IrpQueue;
|
||||
|
@ -581,28 +581,23 @@ static LONG smartcard_GetStatusChangeA_Decode(SMARTCARD_DEVICE* smartcard,
|
||||
static LONG smartcard_GetStatusChangeA_Call(SMARTCARD_DEVICE* smartcard,
|
||||
SMARTCARD_OPERATION* operation)
|
||||
{
|
||||
LONG status;
|
||||
UINT32 index;
|
||||
GetStatusChange_Return ret;
|
||||
LPSCARD_READERSTATEA rgReaderState = NULL;
|
||||
IRP* irp = operation->irp;
|
||||
GetStatusChangeA_Call* call = operation->call;
|
||||
status = ret.ReturnCode = SCardGetStatusChangeA(operation->hContext,
|
||||
call->dwTimeOut, call->rgReaderStates, call->cReaders);
|
||||
|
||||
if (status && (status != SCARD_E_TIMEOUT) && (status != SCARD_E_CANCELLED))
|
||||
{
|
||||
call->cReaders = 0;
|
||||
}
|
||||
|
||||
ret.ReturnCode = SCardGetStatusChangeA(operation->hContext, call->dwTimeOut, call->rgReaderStates,
|
||||
call->cReaders);
|
||||
ret.cReaders = call->cReaders;
|
||||
ret.rgReaderStates = NULL;
|
||||
|
||||
if (ret.cReaders > 0)
|
||||
{
|
||||
ret.rgReaderStates = (ReaderState_Return*) calloc(ret.cReaders, sizeof(ReaderState_Return));
|
||||
|
||||
if (!ret.rgReaderStates)
|
||||
return STATUS_NO_MEMORY;
|
||||
if (!ret.rgReaderStates)
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
for (index = 0; index < ret.cReaders; index++)
|
||||
{
|
||||
@ -613,12 +608,7 @@ static LONG smartcard_GetStatusChangeA_Call(SMARTCARD_DEVICE* smartcard,
|
||||
}
|
||||
|
||||
smartcard_trace_get_status_change_return(smartcard, &ret, FALSE);
|
||||
|
||||
if ((status = smartcard_pack_get_status_change_return(smartcard, irp->output, &ret)))
|
||||
{
|
||||
WLog_ERR(TAG, "smartcard_pack_get_status_change_return failed with error %"PRId32"", status);
|
||||
return status;
|
||||
}
|
||||
smartcard_pack_get_status_change_return(smartcard, irp->output, &ret);
|
||||
|
||||
if (call->rgReaderStates)
|
||||
{
|
||||
@ -657,28 +647,23 @@ static LONG smartcard_GetStatusChangeW_Decode(SMARTCARD_DEVICE* smartcard,
|
||||
static LONG smartcard_GetStatusChangeW_Call(SMARTCARD_DEVICE* smartcard,
|
||||
SMARTCARD_OPERATION* operation)
|
||||
{
|
||||
LONG status;
|
||||
UINT32 index;
|
||||
GetStatusChange_Return ret;
|
||||
LPSCARD_READERSTATEW rgReaderState = NULL;
|
||||
IRP* irp = operation->irp;
|
||||
GetStatusChangeW_Call* call = operation->call;
|
||||
status = ret.ReturnCode = SCardGetStatusChangeW(operation->hContext, call->dwTimeOut,
|
||||
call->rgReaderStates, call->cReaders);
|
||||
|
||||
if (status && (status != SCARD_E_TIMEOUT) && (status != SCARD_E_CANCELLED))
|
||||
{
|
||||
call->cReaders = 0;
|
||||
}
|
||||
|
||||
ret.ReturnCode = SCardGetStatusChangeW(operation->hContext, call->dwTimeOut,
|
||||
call->rgReaderStates, call->cReaders);
|
||||
ret.cReaders = call->cReaders;
|
||||
ret.rgReaderStates = NULL;
|
||||
|
||||
if (ret.cReaders > 0)
|
||||
{
|
||||
ret.rgReaderStates = (ReaderState_Return*) calloc(ret.cReaders, sizeof(ReaderState_Return));
|
||||
|
||||
if (!ret.rgReaderStates)
|
||||
return STATUS_NO_MEMORY;
|
||||
if (!ret.rgReaderStates)
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
for (index = 0; index < ret.cReaders; index++)
|
||||
{
|
||||
@ -689,12 +674,7 @@ static LONG smartcard_GetStatusChangeW_Call(SMARTCARD_DEVICE* smartcard,
|
||||
}
|
||||
|
||||
smartcard_trace_get_status_change_return(smartcard, &ret, TRUE);
|
||||
|
||||
if ((status = smartcard_pack_get_status_change_return(smartcard, irp->output, &ret)))
|
||||
{
|
||||
WLog_ERR(TAG, "smartcard_pack_get_status_change_return failed with error %"PRId32"", status);
|
||||
return status;
|
||||
}
|
||||
smartcard_pack_get_status_change_return(smartcard, irp->output, &ret);
|
||||
|
||||
if (call->rgReaderStates)
|
||||
{
|
||||
@ -787,17 +767,20 @@ static LONG smartcard_ConnectA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERA
|
||||
if (status)
|
||||
{
|
||||
WLog_ERR(TAG, "SCardConnectA failed with error %"PRId32"", status);
|
||||
return status;
|
||||
goto out_fail;
|
||||
}
|
||||
|
||||
if ((status = smartcard_pack_connect_return(smartcard, irp->output, &ret)))
|
||||
{
|
||||
WLog_ERR(TAG, "smartcard_pack_connect_return failed with error %"PRId32"", status);
|
||||
return status;
|
||||
goto out_fail;
|
||||
}
|
||||
|
||||
status = ret.ReturnCode;
|
||||
|
||||
out_fail:
|
||||
free(call->szReader);
|
||||
return ret.ReturnCode;
|
||||
return status;
|
||||
}
|
||||
|
||||
static LONG smartcard_ConnectW_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation)
|
||||
@ -843,17 +826,20 @@ static LONG smartcard_ConnectW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERA
|
||||
if (status)
|
||||
{
|
||||
WLog_ERR(TAG, "SCardConnectW failed with error %"PRId32"", status);
|
||||
return status;
|
||||
goto out_fail;
|
||||
}
|
||||
|
||||
if ((status = smartcard_pack_connect_return(smartcard, irp->output, &ret)))
|
||||
{
|
||||
WLog_ERR(TAG, "smartcard_pack_connect_return failed with error %"PRId32"", status);
|
||||
return status;
|
||||
goto out_fail;
|
||||
}
|
||||
|
||||
status = ret.ReturnCode;
|
||||
|
||||
out_fail:
|
||||
free(call->szReader);
|
||||
return ret.ReturnCode;
|
||||
return status;
|
||||
}
|
||||
|
||||
static LONG smartcard_Reconnect_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation)
|
||||
@ -1064,23 +1050,36 @@ static LONG smartcard_StatusA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERAT
|
||||
LONG status;
|
||||
Status_Return ret = { 0 };
|
||||
DWORD cchReaderLen = 0;
|
||||
DWORD cbAtrLen = 0;
|
||||
LPSTR mszReaderNames = NULL;
|
||||
IRP* irp = operation->irp;
|
||||
Status_Call* call = operation->call;
|
||||
ZeroMemory(ret.pbAtr, 32);
|
||||
|
||||
if (call->cbAtrLen > 32)
|
||||
call->cbAtrLen = 32;
|
||||
|
||||
ret.cbAtrLen = call->cbAtrLen;
|
||||
ZeroMemory(ret.pbAtr, 32);
|
||||
cchReaderLen = SCARD_AUTOALLOCATE;
|
||||
status = ret.ReturnCode = SCardStatusA(operation->hCard, (LPSTR) &mszReaderNames, &cchReaderLen,
|
||||
&ret.dwState, &ret.dwProtocol, (BYTE*) &ret.pbAtr, &ret.cbAtrLen);
|
||||
cbAtrLen = call->cbAtrLen;
|
||||
|
||||
if (call->fmszReaderNamesIsNULL)
|
||||
cchReaderLen = 0;
|
||||
else
|
||||
cchReaderLen = SCARD_AUTOALLOCATE;
|
||||
|
||||
status = ret.ReturnCode = SCardStatusA(operation->hCard,
|
||||
call->fmszReaderNamesIsNULL ? NULL : (LPSTR) &mszReaderNames,
|
||||
&cchReaderLen, &ret.dwState, &ret.dwProtocol,
|
||||
cbAtrLen ? (BYTE*) &ret.pbAtr : NULL, &cbAtrLen);
|
||||
|
||||
if (status == SCARD_S_SUCCESS)
|
||||
{
|
||||
ret.mszReaderNames = (BYTE*) mszReaderNames;
|
||||
if (!call->fmszReaderNamesIsNULL)
|
||||
ret.mszReaderNames = (BYTE*) mszReaderNames;
|
||||
|
||||
ret.cBytes = cchReaderLen;
|
||||
|
||||
if (call->cbAtrLen)
|
||||
ret.cbAtrLen = cbAtrLen;
|
||||
}
|
||||
|
||||
smartcard_trace_status_return(smartcard, &ret, FALSE);
|
||||
@ -1092,7 +1091,9 @@ static LONG smartcard_StatusA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERAT
|
||||
}
|
||||
|
||||
if (mszReaderNames)
|
||||
{
|
||||
SCardFreeMemory(operation->hContext, mszReaderNames);
|
||||
}
|
||||
|
||||
return ret.ReturnCode;
|
||||
}
|
||||
@ -1124,17 +1125,33 @@ static LONG smartcard_StatusW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERAT
|
||||
LPWSTR mszReaderNames = NULL;
|
||||
IRP* irp = operation->irp;
|
||||
Status_Call* call = operation->call;
|
||||
DWORD cbAtrLen;
|
||||
|
||||
if (call->cbAtrLen > 32)
|
||||
call->cbAtrLen = 32;
|
||||
|
||||
ret.cbAtrLen = call->cbAtrLen;
|
||||
if (call->fmszReaderNamesIsNULL)
|
||||
cchReaderLen = 0;
|
||||
else
|
||||
cchReaderLen = SCARD_AUTOALLOCATE;
|
||||
|
||||
cbAtrLen = call->cbAtrLen;
|
||||
|
||||
ZeroMemory(ret.pbAtr, 32);
|
||||
cchReaderLen = SCARD_AUTOALLOCATE;
|
||||
status = ret.ReturnCode = SCardStatusW(operation->hCard, (LPWSTR) &mszReaderNames, &cchReaderLen,
|
||||
&ret.dwState, &ret.dwProtocol, (BYTE*) &ret.pbAtr, &ret.cbAtrLen);
|
||||
ret.mszReaderNames = (BYTE*) mszReaderNames;
|
||||
ret.cBytes = cchReaderLen * 2;
|
||||
status = ret.ReturnCode = SCardStatusW(operation->hCard,
|
||||
call->fmszReaderNamesIsNULL ? NULL : (LPWSTR) &mszReaderNames,
|
||||
&cchReaderLen, &ret.dwState, &ret.dwProtocol, (BYTE*) &ret.pbAtr, &cbAtrLen);
|
||||
|
||||
if (status == SCARD_S_SUCCESS)
|
||||
{
|
||||
if (!call->fmszReaderNamesIsNULL)
|
||||
ret.mszReaderNames = (BYTE*) mszReaderNames;
|
||||
|
||||
ret.cBytes = cchReaderLen;
|
||||
|
||||
if (call->cbAtrLen)
|
||||
ret.cbAtrLen = cbAtrLen;
|
||||
}
|
||||
smartcard_trace_status_return(smartcard, &ret, TRUE);
|
||||
|
||||
if ((status = smartcard_pack_status_return(smartcard, irp->output, &ret)))
|
||||
@ -2022,13 +2039,12 @@ LONG smartcard_irp_device_control_call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OP
|
||||
SCardGetErrorString(result), result);
|
||||
}
|
||||
|
||||
irp->IoStatus = 0;
|
||||
irp->IoStatus = STATUS_SUCCESS;
|
||||
|
||||
if ((result & 0xC0000000) == 0xC0000000)
|
||||
{
|
||||
/* NTSTATUS error */
|
||||
irp->IoStatus = (UINT32)result;
|
||||
Stream_SetPosition(irp->output, RDPDR_DEVICE_IO_RESPONSE_LENGTH);
|
||||
WLog_WARN(TAG, "IRP failure: %s (0x%08"PRIX32"), ntstatus: 0x%08"PRIX32"",
|
||||
smartcard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, result);
|
||||
}
|
||||
@ -2039,21 +2055,9 @@ LONG smartcard_irp_device_control_call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OP
|
||||
Stream_SetPosition(irp->output, RDPDR_DEVICE_IO_RESPONSE_LENGTH);
|
||||
/* Device Control Response */
|
||||
Stream_Write_UINT32(irp->output, outputBufferLength); /* OutputBufferLength (4 bytes) */
|
||||
|
||||
if ((result = smartcard_pack_common_type_header(smartcard,
|
||||
irp->output))) /* CommonTypeHeader (8 bytes) */
|
||||
{
|
||||
WLog_ERR(TAG, "smartcard_pack_common_type_header failed with error %"PRId32"", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
if ((result = smartcard_pack_private_type_header(smartcard, irp->output,
|
||||
objectBufferLength))) /* PrivateTypeHeader (8 bytes) */
|
||||
{
|
||||
WLog_ERR(TAG, "smartcard_pack_private_type_header failed with error %"PRId32"", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
smartcard_pack_common_type_header(smartcard, irp->output); /* CommonTypeHeader (8 bytes) */
|
||||
smartcard_pack_private_type_header(smartcard, irp->output,
|
||||
objectBufferLength); /* PrivateTypeHeader (8 bytes) */
|
||||
Stream_Write_UINT32(irp->output, result); /* Result (4 bytes) */
|
||||
Stream_SetPosition(irp->output, Stream_Length(irp->output));
|
||||
return SCARD_S_SUCCESS;
|
||||
|
@ -75,13 +75,12 @@ LONG smartcard_unpack_common_type_header(SMARTCARD_DEVICE* smartcard, wStream* s
|
||||
return SCARD_S_SUCCESS;
|
||||
}
|
||||
|
||||
LONG smartcard_pack_common_type_header(SMARTCARD_DEVICE* smartcard, wStream* s)
|
||||
void smartcard_pack_common_type_header(SMARTCARD_DEVICE* smartcard, wStream* s)
|
||||
{
|
||||
Stream_Write_UINT8(s, 1); /* Version (1 byte) */
|
||||
Stream_Write_UINT8(s, 0x10); /* Endianness (1 byte) */
|
||||
Stream_Write_UINT16(s, 8); /* CommonHeaderLength (2 bytes) */
|
||||
Stream_Write_UINT32(s, 0xCCCCCCCC); /* Filler (4 bytes), should be 0xCCCCCCCC */
|
||||
return SCARD_S_SUCCESS;
|
||||
}
|
||||
|
||||
LONG smartcard_unpack_private_type_header(SMARTCARD_DEVICE* smartcard, wStream* s)
|
||||
@ -116,12 +115,11 @@ LONG smartcard_unpack_private_type_header(SMARTCARD_DEVICE* smartcard, wStream*
|
||||
return SCARD_S_SUCCESS;
|
||||
}
|
||||
|
||||
LONG smartcard_pack_private_type_header(SMARTCARD_DEVICE* smartcard, wStream* s,
|
||||
void smartcard_pack_private_type_header(SMARTCARD_DEVICE* smartcard, wStream* s,
|
||||
UINT32 objectBufferLength)
|
||||
{
|
||||
Stream_Write_UINT32(s, objectBufferLength); /* ObjectBufferLength (4 bytes) */
|
||||
Stream_Write_UINT32(s, 0x00000000); /* Filler (4 bytes), should be 0x00000000 */
|
||||
return SCARD_S_SUCCESS;
|
||||
}
|
||||
|
||||
LONG smartcard_unpack_read_size_align(SMARTCARD_DEVICE* smartcard, wStream* s, UINT32 size,
|
||||
@ -850,7 +848,7 @@ void smartcard_trace_list_readers_return(SMARTCARD_DEVICE* smartcard, ListReader
|
||||
CopyMemory(mszA, ret->msz, ret->cBytes);
|
||||
}
|
||||
|
||||
for (index = 0; index < length - 2; index++)
|
||||
for (index = 0; index < length - 1; index++)
|
||||
{
|
||||
if (mszA[index] == '\0')
|
||||
mszA[index] = ',';
|
||||
@ -1863,32 +1861,34 @@ void smartcard_trace_status_return(SMARTCARD_DEVICE* smartcard, Status_Return* r
|
||||
if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG))
|
||||
return;
|
||||
|
||||
if (unicode)
|
||||
if (ret->mszReaderNames)
|
||||
{
|
||||
length = ret->cBytes / 2;
|
||||
|
||||
if (ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) ret->mszReaderNames, (int)length,
|
||||
&mszReaderNamesA, 0, NULL, NULL) < 1)
|
||||
if (unicode)
|
||||
{
|
||||
WLog_ERR(TAG, "ConvertFromUnicode failed");
|
||||
return;
|
||||
length = ret->cBytes / 2;
|
||||
|
||||
if (ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) ret->mszReaderNames, (int) length,
|
||||
&mszReaderNamesA, 0, NULL, NULL) < 1)
|
||||
{
|
||||
WLog_ERR(TAG, "ConvertFromUnicode failed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
length = (int) ret->cBytes;
|
||||
mszReaderNamesA = (char*) malloc(length);
|
||||
|
||||
if (!mszReaderNamesA)
|
||||
{
|
||||
WLog_ERR(TAG, "malloc failed!");
|
||||
return;
|
||||
}
|
||||
|
||||
CopyMemory(mszReaderNamesA, ret->mszReaderNames, ret->cBytes);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
length = (int) ret->cBytes;
|
||||
mszReaderNamesA = (char*) malloc(length);
|
||||
|
||||
if (!mszReaderNamesA)
|
||||
{
|
||||
WLog_ERR(TAG, "malloc failed!");
|
||||
return;
|
||||
}
|
||||
|
||||
CopyMemory(mszReaderNamesA, ret->mszReaderNames, ret->cBytes);
|
||||
}
|
||||
|
||||
if (!mszReaderNamesA)
|
||||
length = 0;
|
||||
|
||||
if (length > 2)
|
||||
|
@ -452,10 +452,10 @@ void smartcard_scard_handle_native_to_redir(SMARTCARD_DEVICE* smartcard, REDIR_S
|
||||
SCARDHANDLE hCard);
|
||||
|
||||
LONG smartcard_unpack_common_type_header(SMARTCARD_DEVICE* smartcard, wStream* s);
|
||||
LONG smartcard_pack_common_type_header(SMARTCARD_DEVICE* smartcard, wStream* s);
|
||||
void smartcard_pack_common_type_header(SMARTCARD_DEVICE* smartcard, wStream* s);
|
||||
|
||||
LONG smartcard_unpack_private_type_header(SMARTCARD_DEVICE* smartcard, wStream* s);
|
||||
LONG smartcard_pack_private_type_header(SMARTCARD_DEVICE* smartcard, wStream* s,
|
||||
void smartcard_pack_private_type_header(SMARTCARD_DEVICE* smartcard, wStream* s,
|
||||
UINT32 objectBufferLength);
|
||||
|
||||
LONG smartcard_unpack_redir_scard_context(SMARTCARD_DEVICE* smartcard, wStream* s,
|
||||
|
@ -476,43 +476,29 @@ BOOL freerdp_client_add_device_channel(rdpSettings* settings, int count,
|
||||
settings->RedirectSmartCards = TRUE;
|
||||
settings->DeviceRedirection = TRUE;
|
||||
|
||||
if (count > 1)
|
||||
smartcard = (RDPDR_SMARTCARD*) calloc(1, sizeof(RDPDR_SMARTCARD));
|
||||
|
||||
if (!smartcard)
|
||||
return FALSE;
|
||||
|
||||
smartcard->Type = RDPDR_DTYP_SMARTCARD;
|
||||
|
||||
if (count > 1 && strlen(params[1]))
|
||||
{
|
||||
smartcard = (RDPDR_SMARTCARD*) calloc(1, sizeof(RDPDR_SMARTCARD));
|
||||
|
||||
if (!smartcard)
|
||||
return FALSE;
|
||||
|
||||
smartcard->Type = RDPDR_DTYP_SMARTCARD;
|
||||
|
||||
if (count > 1)
|
||||
if (!(smartcard->Name = _strdup(params[1])))
|
||||
{
|
||||
if (!(smartcard->Name = _strdup(params[1])))
|
||||
{
|
||||
free(smartcard);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (count > 2)
|
||||
{
|
||||
if (!(smartcard->Path = _strdup(params[2])))
|
||||
{
|
||||
free(smartcard->Name);
|
||||
free(smartcard);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!freerdp_device_collection_add(settings, (RDPDR_DEVICE*) smartcard))
|
||||
{
|
||||
free(smartcard->Path);
|
||||
free(smartcard->Name);
|
||||
free(smartcard);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!freerdp_device_collection_add(settings, (RDPDR_DEVICE*) smartcard))
|
||||
{
|
||||
free(smartcard->Name);
|
||||
free(smartcard);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else if (strcmp(params[0], "serial") == 0)
|
||||
|
@ -446,7 +446,6 @@ struct _RDPDR_SMARTCARD
|
||||
UINT32 Id;
|
||||
UINT32 Type;
|
||||
char* Name;
|
||||
char* Path;
|
||||
};
|
||||
typedef struct _RDPDR_SMARTCARD RDPDR_SMARTCARD;
|
||||
|
||||
|
@ -307,17 +307,8 @@ out_print_name_error:
|
||||
goto out_smartc_name_error;
|
||||
}
|
||||
|
||||
if (smartcard->Path)
|
||||
{
|
||||
_smartcard->Path = _strdup(smartcard->Path);
|
||||
if (!_smartcard->Path)
|
||||
goto out_smartc_path_error;
|
||||
}
|
||||
|
||||
return (RDPDR_DEVICE*) _smartcard;
|
||||
|
||||
out_smartc_path_error:
|
||||
free(_smartcard->Name);
|
||||
out_smartc_name_error:
|
||||
free(_smartcard);
|
||||
return NULL;
|
||||
@ -428,7 +419,7 @@ void freerdp_device_collection_free(rdpSettings* settings)
|
||||
}
|
||||
else if (settings->DeviceArray[index]->Type == RDPDR_DTYP_SMARTCARD)
|
||||
{
|
||||
free(((RDPDR_SMARTCARD*) device)->Path);
|
||||
|
||||
}
|
||||
else if (settings->DeviceArray[index]->Type == RDPDR_DTYP_SERIAL)
|
||||
{
|
||||
|
@ -789,8 +789,6 @@ WINSCARDAPI LONG WINAPI SCardListReadersWithDeviceInstanceIdW(SCARDCONTEXT hCont
|
||||
|
||||
WINSCARDAPI LONG WINAPI SCardAudit(SCARDCONTEXT hContext, DWORD dwEvent);
|
||||
|
||||
WINSCARDAPI LONG WINAPI SCardAddReaderName(HANDLE* key, LPSTR readerName);
|
||||
|
||||
#ifdef UNICODE
|
||||
#define SCardListReaderGroups SCardListReaderGroupsW
|
||||
#define SCardListReaders SCardListReadersW
|
||||
@ -1045,8 +1043,6 @@ typedef LONG(WINAPI* fnSCardListReadersWithDeviceInstanceIdW)(SCARDCONTEXT hCont
|
||||
|
||||
typedef LONG(WINAPI* fnSCardAudit)(SCARDCONTEXT hContext, DWORD dwEvent);
|
||||
|
||||
typedef LONG(WINAPI* fnSCardAddReaderName)(HANDLE* key, LPSTR readerName);
|
||||
|
||||
struct _SCardApiFunctionTable
|
||||
{
|
||||
DWORD dwVersion;
|
||||
@ -1128,7 +1124,6 @@ struct _SCardApiFunctionTable
|
||||
fnSCardListReadersWithDeviceInstanceIdA pfnSCardListReadersWithDeviceInstanceIdA;
|
||||
fnSCardListReadersWithDeviceInstanceIdW pfnSCardListReadersWithDeviceInstanceIdW;
|
||||
fnSCardAudit pfnSCardAudit;
|
||||
fnSCardAddReaderName pfnSCardAddReaderName;
|
||||
};
|
||||
|
||||
typedef struct _SCardApiFunctionTable SCardApiFunctionTable;
|
||||
|
@ -71,4 +71,6 @@ WINPR_API const char* winpr_get_build_date(void);
|
||||
WINPR_API const char* winpr_get_build_revision(void);
|
||||
WINPR_API const char* winpr_get_build_config(void);
|
||||
|
||||
#define WINPR_UNUSED(x) (void)(x)
|
||||
|
||||
#endif /* WINPR_H */
|
||||
|
@ -507,11 +507,6 @@ WINSCARDAPI LONG WINAPI SCardAudit(SCARDCONTEXT hContext, DWORD dwEvent)
|
||||
SCARDAPI_STUB_CALL_LONG(SCardAudit, hContext, dwEvent);
|
||||
}
|
||||
|
||||
WINSCARDAPI LONG WINAPI SCardAddReaderName(HANDLE* key, LPSTR readerName)
|
||||
{
|
||||
SCARDAPI_STUB_CALL_LONG(SCardAddReaderName, key, readerName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extended API
|
||||
*/
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -155,7 +155,6 @@ struct _PCSCFunctionTable
|
||||
PCSC_LPDWORD pcbAttrLen);
|
||||
PCSC_LONG(* pfnSCardSetAttrib)(SCARDHANDLE hCard, PCSC_DWORD dwAttrId, LPCBYTE pbAttr,
|
||||
PCSC_DWORD cbAttrLen);
|
||||
PCSC_LONG(* pfnSCardAddReaderName)(HANDLE* key, LPSTR readerName);
|
||||
};
|
||||
typedef struct _PCSCFunctionTable PCSCFunctionTable;
|
||||
|
||||
|
@ -111,8 +111,7 @@ SCardApiFunctionTable WinSCard_SCardApiFunctionTable =
|
||||
NULL, /* SCardGetReaderDeviceInstanceIdW */
|
||||
NULL, /* SCardListReadersWithDeviceInstanceIdA */
|
||||
NULL, /* SCardListReadersWithDeviceInstanceIdW */
|
||||
NULL, /* SCardAudit */
|
||||
NULL /* SCardAddReaderName */
|
||||
NULL /* SCardAudit */
|
||||
};
|
||||
|
||||
PSCardApiFunctionTable WinSCard_GetSCardApiFunctionTable(void)
|
||||
|
166
winpr/libwinpr/smartcard/test/TestSmartCardStatus.c
Normal file
166
winpr/libwinpr/smartcard/test/TestSmartCardStatus.c
Normal file
@ -0,0 +1,166 @@
|
||||
// compile against PCSC gcc -o scardtest TestSmartCardStatus.c -DPCSC=1 -I /usr/include/PCSC -lpcsclite
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#if defined(__APPLE__) || defined(PCSC)
|
||||
#include <PCSC/winscard.h>
|
||||
#include <PCSC/wintypes.h>
|
||||
#elif defined (__linux__)
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/smartcard.h>
|
||||
#include <winpr/synch.h>
|
||||
#else
|
||||
#include <winscard.h>
|
||||
#endif
|
||||
|
||||
#if defined(PCSC)
|
||||
int main(int argc, char* argv[])
|
||||
#else
|
||||
int TestSmartCardStatus(int argc, char* argv[])
|
||||
#endif
|
||||
{
|
||||
SCARDCONTEXT hContext;
|
||||
LPSTR mszReaders;
|
||||
DWORD cchReaders = 0;
|
||||
DWORD err;
|
||||
SCARDHANDLE hCard;
|
||||
DWORD dwActiveProtocol;
|
||||
char name[100];
|
||||
char* aname = NULL;
|
||||
char* aatr = NULL;
|
||||
DWORD len;
|
||||
BYTE atr[32];
|
||||
DWORD atrlen = 32;
|
||||
DWORD status = 0;
|
||||
DWORD protocol = 0;
|
||||
err = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
|
||||
|
||||
if (err != SCARD_S_SUCCESS)
|
||||
{
|
||||
printf("ScardEstablishedContext: 0x%08x\n", err);
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = SCardListReaders(hContext, "SCard$AllReaders", NULL, &cchReaders);
|
||||
|
||||
if (err != 0)
|
||||
{
|
||||
printf("ScardListReaders: 0x%08x\n", err);
|
||||
return -1;
|
||||
}
|
||||
|
||||
mszReaders = calloc(cchReaders, sizeof(char));
|
||||
|
||||
if (!mszReaders)
|
||||
{
|
||||
printf("calloc\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = SCardListReaders(hContext, "SCard$AllReaders", mszReaders, &cchReaders);
|
||||
|
||||
if (err != SCARD_S_SUCCESS)
|
||||
{
|
||||
printf("ScardListReaders: 0x%08x\n", err);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Reader: %s\n", mszReaders);
|
||||
err = SCardConnect(hContext, mszReaders, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
|
||||
&hCard, &dwActiveProtocol);
|
||||
|
||||
if (err != SCARD_S_SUCCESS)
|
||||
{
|
||||
printf("ScardConnect: 0x%08x\n", err);
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(mszReaders);
|
||||
|
||||
|
||||
printf("# test 1 - get reader length\n");
|
||||
err = SCardStatus(hCard, NULL, &len, NULL, NULL, NULL, NULL);
|
||||
if (err != SCARD_S_SUCCESS)
|
||||
{
|
||||
printf("SCardStatus: 0x%08x\n", err);
|
||||
return -1;
|
||||
}
|
||||
printf("reader name length: %u\n", len);
|
||||
|
||||
|
||||
printf("# test 2 - get reader name value\n");
|
||||
err = SCardStatus(hCard, name, &len, NULL, NULL, NULL, NULL);
|
||||
if (err != SCARD_S_SUCCESS)
|
||||
{
|
||||
printf("SCardStatus: 0x%08x\n", err);
|
||||
return -1;
|
||||
}
|
||||
printf("Reader name: %s (%ld)\n", name, strlen(name));
|
||||
|
||||
|
||||
printf("# test 3 - get all values - pre allocated\n");
|
||||
err = SCardStatus(hCard, name, &len, &status, &protocol, atr, &atrlen);
|
||||
if (err != SCARD_S_SUCCESS)
|
||||
{
|
||||
printf("SCardStatus: 0x%08x\n", err);
|
||||
return -1;
|
||||
}
|
||||
printf("Reader name: %s (%ld/len %u)\n", name, strlen(name), len);
|
||||
printf("status: 0x%08X\n", status);
|
||||
printf("proto: 0x%08X\n", protocol);
|
||||
printf("atrlen: %u\n", atrlen);
|
||||
|
||||
|
||||
printf("# test 4 - get all values - auto allocate\n");
|
||||
len = atrlen = SCARD_AUTOALLOCATE;
|
||||
err = SCardStatus(hCard, (LPSTR)&aname, &len, &status, &protocol, (LPBYTE)&aatr, &atrlen);
|
||||
if (err != SCARD_S_SUCCESS)
|
||||
{
|
||||
printf("SCardStatus: 0x%08x\n", err);
|
||||
return -1;
|
||||
}
|
||||
printf("Reader name: %s (%ld/%u)\n", aname, strlen(aname), len);
|
||||
printf("status: 0x%08X\n", status);
|
||||
printf("proto: 0x%08X\n", protocol);
|
||||
printf("atrlen: %u\n", atrlen);
|
||||
SCardFreeMemory(hContext, aname);
|
||||
SCardFreeMemory(hContext, aatr);
|
||||
|
||||
|
||||
printf("# test 5 - get status and protocol only\n");
|
||||
err = SCardStatus(hCard, NULL, NULL, &status, &protocol, NULL, NULL);
|
||||
if (err != SCARD_S_SUCCESS)
|
||||
{
|
||||
printf("SCardStatus: 0x%08x\n", err);
|
||||
return -1;
|
||||
}
|
||||
printf("status: 0x%08X\n", status);
|
||||
printf("proto: 0x%08X\n", protocol);
|
||||
|
||||
|
||||
printf("# test 6 - get atr only auto allocated\n");
|
||||
atrlen = SCARD_AUTOALLOCATE;
|
||||
err = SCardStatus(hCard, NULL, NULL, NULL, NULL, (LPBYTE)&aatr, &atrlen);
|
||||
if (err != SCARD_S_SUCCESS)
|
||||
{
|
||||
printf("SCardStatus: 0x%08x\n", err);
|
||||
return -1;
|
||||
}
|
||||
printf("atrlen: %u\n", atrlen);
|
||||
SCardFreeMemory(hContext, aatr);
|
||||
|
||||
|
||||
printf("# test 7 - get atr only pre allocated\n");
|
||||
atrlen = 32;
|
||||
err = SCardStatus(hCard, NULL, NULL, NULL, NULL, atr, &atrlen);
|
||||
if (err != SCARD_S_SUCCESS)
|
||||
{
|
||||
printf("SCardStatus: 0x%08x\n", err);
|
||||
return -1;
|
||||
}
|
||||
printf("atrlen: %u\n", atrlen);
|
||||
SCardDisconnect(hCard, SCARD_LEAVE_CARD);
|
||||
SCardReleaseContext(hContext);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user