Merge pull request #4312 from bmiklautz/smartcard-cleanup

Smartcard fixes and cleanup
This commit is contained in:
akallabeth 2017-12-14 16:56:29 +01:00 committed by GitHub
commit 097f8edd97
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 463 additions and 815 deletions

View File

@ -385,17 +385,17 @@ UINT smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
asyncIrp = TRUE; 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) switch (operation->ioControlCode)
{ {
case SCARD_IOCTL_ESTABLISHCONTEXT: case SCARD_IOCTL_ESTABLISHCONTEXT:
case SCARD_IOCTL_RELEASECONTEXT: case SCARD_IOCTL_RELEASECONTEXT:
case SCARD_IOCTL_ISVALIDCONTEXT: 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_LISTREADERGROUPSA:
case SCARD_IOCTL_LISTREADERGROUPSW: case SCARD_IOCTL_LISTREADERGROUPSW:
case SCARD_IOCTL_LISTREADERSA: case SCARD_IOCTL_LISTREADERSA:
@ -416,21 +416,14 @@ UINT smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
case SCARD_IOCTL_LOCATECARDSW: case SCARD_IOCTL_LOCATECARDSW:
case SCARD_IOCTL_LOCATECARDSBYATRA: case SCARD_IOCTL_LOCATECARDSBYATRA:
case SCARD_IOCTL_LOCATECARDSBYATRW: case SCARD_IOCTL_LOCATECARDSBYATRW:
case SCARD_IOCTL_CANCEL:
case SCARD_IOCTL_READCACHEA: case SCARD_IOCTL_READCACHEA:
case SCARD_IOCTL_READCACHEW: case SCARD_IOCTL_READCACHEW:
case SCARD_IOCTL_WRITECACHEA: case SCARD_IOCTL_WRITECACHEA:
case SCARD_IOCTL_WRITECACHEW: case SCARD_IOCTL_WRITECACHEW:
case SCARD_IOCTL_GETREADERICON: case SCARD_IOCTL_GETREADERICON:
case SCARD_IOCTL_GETDEVICETYPEID: case SCARD_IOCTL_GETDEVICETYPEID:
asyncIrp = FALSE;
break;
case SCARD_IOCTL_GETSTATUSCHANGEA: case SCARD_IOCTL_GETSTATUSCHANGEA:
case SCARD_IOCTL_GETSTATUSCHANGEW: case SCARD_IOCTL_GETSTATUSCHANGEW:
asyncIrp = TRUE;
break;
case SCARD_IOCTL_CONNECTA: case SCARD_IOCTL_CONNECTA:
case SCARD_IOCTL_CONNECTW: case SCARD_IOCTL_CONNECTW:
case SCARD_IOCTL_RECONNECT: case SCARD_IOCTL_RECONNECT:
@ -447,11 +440,6 @@ UINT smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
case SCARD_IOCTL_GETTRANSMITCOUNT: case SCARD_IOCTL_GETTRANSMITCOUNT:
asyncIrp = TRUE; asyncIrp = TRUE;
break; break;
case SCARD_IOCTL_ACCESSSTARTEDEVENT:
case SCARD_IOCTL_RELEASESTARTEDEVENT:
asyncIrp = FALSE;
break;
} }
pContext = ListDictionary_GetItemValue(smartcard->rgSCardContextList, 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) UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
{ {
char* name;
char* path;
size_t length; size_t length;
int ck;
RDPDR_SMARTCARD* device; RDPDR_SMARTCARD* device;
SMARTCARD_DEVICE* smartcard; SMARTCARD_DEVICE* smartcard;
LONG status;
UINT error = CHANNEL_RC_NO_MEMORY; UINT error = CHANNEL_RC_NO_MEMORY;
device = (RDPDR_SMARTCARD*) pEntryPoints->device; device = (RDPDR_SMARTCARD*) pEntryPoints->device;
name = device->Name;
path = device->Path;
smartcard = (SMARTCARD_DEVICE*) calloc(1, sizeof(SMARTCARD_DEVICE)); smartcard = (SMARTCARD_DEVICE*) calloc(1, sizeof(SMARTCARD_DEVICE));
if (!smartcard) if (!smartcard)
@ -724,29 +706,6 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
} }
Stream_Write(smartcard->device.data, "SCARD", 6); 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); smartcard->IrpQueue = MessageQueue_New(NULL);

View File

@ -110,9 +110,6 @@ struct _SMARTCARD_DEVICE
{ {
DEVICE device; DEVICE device;
char* name;
char* path;
HANDLE thread; HANDLE thread;
HANDLE StartedEvent; HANDLE StartedEvent;
wMessageQueue* IrpQueue; wMessageQueue* IrpQueue;

View File

@ -581,28 +581,23 @@ static LONG smartcard_GetStatusChangeA_Decode(SMARTCARD_DEVICE* smartcard,
static LONG smartcard_GetStatusChangeA_Call(SMARTCARD_DEVICE* smartcard, static LONG smartcard_GetStatusChangeA_Call(SMARTCARD_DEVICE* smartcard,
SMARTCARD_OPERATION* operation) SMARTCARD_OPERATION* operation)
{ {
LONG status;
UINT32 index; UINT32 index;
GetStatusChange_Return ret; GetStatusChange_Return ret;
LPSCARD_READERSTATEA rgReaderState = NULL; LPSCARD_READERSTATEA rgReaderState = NULL;
IRP* irp = operation->irp; IRP* irp = operation->irp;
GetStatusChangeA_Call* call = operation->call; GetStatusChangeA_Call* call = operation->call;
status = ret.ReturnCode = SCardGetStatusChangeA(operation->hContext, ret.ReturnCode = SCardGetStatusChangeA(operation->hContext, call->dwTimeOut, call->rgReaderStates,
call->dwTimeOut, call->rgReaderStates, call->cReaders); call->cReaders);
if (status && (status != SCARD_E_TIMEOUT) && (status != SCARD_E_CANCELLED))
{
call->cReaders = 0;
}
ret.cReaders = call->cReaders; ret.cReaders = call->cReaders;
ret.rgReaderStates = NULL; ret.rgReaderStates = NULL;
if (ret.cReaders > 0) if (ret.cReaders > 0)
{
ret.rgReaderStates = (ReaderState_Return*) calloc(ret.cReaders, sizeof(ReaderState_Return)); ret.rgReaderStates = (ReaderState_Return*) calloc(ret.cReaders, sizeof(ReaderState_Return));
if (!ret.rgReaderStates) if (!ret.rgReaderStates)
return STATUS_NO_MEMORY; return STATUS_NO_MEMORY;
}
for (index = 0; index < ret.cReaders; index++) 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); smartcard_trace_get_status_change_return(smartcard, &ret, FALSE);
smartcard_pack_get_status_change_return(smartcard, irp->output, &ret);
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;
}
if (call->rgReaderStates) if (call->rgReaderStates)
{ {
@ -657,28 +647,23 @@ static LONG smartcard_GetStatusChangeW_Decode(SMARTCARD_DEVICE* smartcard,
static LONG smartcard_GetStatusChangeW_Call(SMARTCARD_DEVICE* smartcard, static LONG smartcard_GetStatusChangeW_Call(SMARTCARD_DEVICE* smartcard,
SMARTCARD_OPERATION* operation) SMARTCARD_OPERATION* operation)
{ {
LONG status;
UINT32 index; UINT32 index;
GetStatusChange_Return ret; GetStatusChange_Return ret;
LPSCARD_READERSTATEW rgReaderState = NULL; LPSCARD_READERSTATEW rgReaderState = NULL;
IRP* irp = operation->irp; IRP* irp = operation->irp;
GetStatusChangeW_Call* call = operation->call; GetStatusChangeW_Call* call = operation->call;
status = ret.ReturnCode = SCardGetStatusChangeW(operation->hContext, call->dwTimeOut, ret.ReturnCode = SCardGetStatusChangeW(operation->hContext, call->dwTimeOut,
call->rgReaderStates, call->cReaders); call->rgReaderStates, call->cReaders);
if (status && (status != SCARD_E_TIMEOUT) && (status != SCARD_E_CANCELLED))
{
call->cReaders = 0;
}
ret.cReaders = call->cReaders; ret.cReaders = call->cReaders;
ret.rgReaderStates = NULL; ret.rgReaderStates = NULL;
if (ret.cReaders > 0) if (ret.cReaders > 0)
{
ret.rgReaderStates = (ReaderState_Return*) calloc(ret.cReaders, sizeof(ReaderState_Return)); ret.rgReaderStates = (ReaderState_Return*) calloc(ret.cReaders, sizeof(ReaderState_Return));
if (!ret.rgReaderStates) if (!ret.rgReaderStates)
return STATUS_NO_MEMORY; return STATUS_NO_MEMORY;
}
for (index = 0; index < ret.cReaders; index++) 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); smartcard_trace_get_status_change_return(smartcard, &ret, TRUE);
smartcard_pack_get_status_change_return(smartcard, irp->output, &ret);
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;
}
if (call->rgReaderStates) if (call->rgReaderStates)
{ {
@ -787,17 +767,20 @@ static LONG smartcard_ConnectA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERA
if (status) if (status)
{ {
WLog_ERR(TAG, "SCardConnectA failed with error %"PRId32"", 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))) if ((status = smartcard_pack_connect_return(smartcard, irp->output, &ret)))
{ {
WLog_ERR(TAG, "smartcard_pack_connect_return failed with error %"PRId32"", status); 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); free(call->szReader);
return ret.ReturnCode; return status;
} }
static LONG smartcard_ConnectW_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) 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) if (status)
{ {
WLog_ERR(TAG, "SCardConnectW failed with error %"PRId32"", 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))) if ((status = smartcard_pack_connect_return(smartcard, irp->output, &ret)))
{ {
WLog_ERR(TAG, "smartcard_pack_connect_return failed with error %"PRId32"", status); 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); free(call->szReader);
return ret.ReturnCode; return status;
} }
static LONG smartcard_Reconnect_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) 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; LONG status;
Status_Return ret = { 0 }; Status_Return ret = { 0 };
DWORD cchReaderLen = 0; DWORD cchReaderLen = 0;
DWORD cbAtrLen = 0;
LPSTR mszReaderNames = NULL; LPSTR mszReaderNames = NULL;
IRP* irp = operation->irp; IRP* irp = operation->irp;
Status_Call* call = operation->call; Status_Call* call = operation->call;
ZeroMemory(ret.pbAtr, 32);
if (call->cbAtrLen > 32) if (call->cbAtrLen > 32)
call->cbAtrLen = 32; call->cbAtrLen = 32;
ret.cbAtrLen = call->cbAtrLen; cbAtrLen = call->cbAtrLen;
ZeroMemory(ret.pbAtr, 32);
cchReaderLen = SCARD_AUTOALLOCATE; if (call->fmszReaderNamesIsNULL)
status = ret.ReturnCode = SCardStatusA(operation->hCard, (LPSTR) &mszReaderNames, &cchReaderLen, cchReaderLen = 0;
&ret.dwState, &ret.dwProtocol, (BYTE*) &ret.pbAtr, &ret.cbAtrLen); 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) if (status == SCARD_S_SUCCESS)
{ {
ret.mszReaderNames = (BYTE*) mszReaderNames; if (!call->fmszReaderNamesIsNULL)
ret.mszReaderNames = (BYTE*) mszReaderNames;
ret.cBytes = cchReaderLen; ret.cBytes = cchReaderLen;
if (call->cbAtrLen)
ret.cbAtrLen = cbAtrLen;
} }
smartcard_trace_status_return(smartcard, &ret, FALSE); smartcard_trace_status_return(smartcard, &ret, FALSE);
@ -1092,7 +1091,9 @@ static LONG smartcard_StatusA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERAT
} }
if (mszReaderNames) if (mszReaderNames)
{
SCardFreeMemory(operation->hContext, mszReaderNames); SCardFreeMemory(operation->hContext, mszReaderNames);
}
return ret.ReturnCode; return ret.ReturnCode;
} }
@ -1124,17 +1125,33 @@ static LONG smartcard_StatusW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERAT
LPWSTR mszReaderNames = NULL; LPWSTR mszReaderNames = NULL;
IRP* irp = operation->irp; IRP* irp = operation->irp;
Status_Call* call = operation->call; Status_Call* call = operation->call;
DWORD cbAtrLen;
if (call->cbAtrLen > 32) if (call->cbAtrLen > 32)
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); ZeroMemory(ret.pbAtr, 32);
cchReaderLen = SCARD_AUTOALLOCATE; status = ret.ReturnCode = SCardStatusW(operation->hCard,
status = ret.ReturnCode = SCardStatusW(operation->hCard, (LPWSTR) &mszReaderNames, &cchReaderLen, call->fmszReaderNamesIsNULL ? NULL : (LPWSTR) &mszReaderNames,
&ret.dwState, &ret.dwProtocol, (BYTE*) &ret.pbAtr, &ret.cbAtrLen); &cchReaderLen, &ret.dwState, &ret.dwProtocol, (BYTE*) &ret.pbAtr, &cbAtrLen);
ret.mszReaderNames = (BYTE*) mszReaderNames;
ret.cBytes = cchReaderLen * 2; 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); smartcard_trace_status_return(smartcard, &ret, TRUE);
if ((status = smartcard_pack_status_return(smartcard, irp->output, &ret))) 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); SCardGetErrorString(result), result);
} }
irp->IoStatus = 0; irp->IoStatus = STATUS_SUCCESS;
if ((result & 0xC0000000) == 0xC0000000) if ((result & 0xC0000000) == 0xC0000000)
{ {
/* NTSTATUS error */ /* NTSTATUS error */
irp->IoStatus = (UINT32)result; 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"", WLog_WARN(TAG, "IRP failure: %s (0x%08"PRIX32"), ntstatus: 0x%08"PRIX32"",
smartcard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, result); 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); 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) */
if ((result = smartcard_pack_common_type_header(smartcard, smartcard_pack_private_type_header(smartcard, irp->output,
irp->output))) /* CommonTypeHeader (8 bytes) */ objectBufferLength); /* PrivateTypeHeader (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;
}
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;

View File

@ -75,13 +75,12 @@ LONG smartcard_unpack_common_type_header(SMARTCARD_DEVICE* smartcard, wStream* s
return SCARD_S_SUCCESS; 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, 1); /* Version (1 byte) */
Stream_Write_UINT8(s, 0x10); /* Endianness (1 byte) */ Stream_Write_UINT8(s, 0x10); /* Endianness (1 byte) */
Stream_Write_UINT16(s, 8); /* CommonHeaderLength (2 bytes) */ Stream_Write_UINT16(s, 8); /* CommonHeaderLength (2 bytes) */
Stream_Write_UINT32(s, 0xCCCCCCCC); /* Filler (4 bytes), should be 0xCCCCCCCC */ 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) 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; 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) UINT32 objectBufferLength)
{ {
Stream_Write_UINT32(s, objectBufferLength); /* ObjectBufferLength (4 bytes) */ Stream_Write_UINT32(s, objectBufferLength); /* ObjectBufferLength (4 bytes) */
Stream_Write_UINT32(s, 0x00000000); /* Filler (4 bytes), should be 0x00000000 */ 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, 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); CopyMemory(mszA, ret->msz, ret->cBytes);
} }
for (index = 0; index < length - 2; index++) for (index = 0; index < length - 1; index++)
{ {
if (mszA[index] == '\0') if (mszA[index] == '\0')
mszA[index] = ','; 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)) if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG))
return; return;
if (unicode) if (ret->mszReaderNames)
{ {
length = ret->cBytes / 2; if (unicode)
if (ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) ret->mszReaderNames, (int)length,
&mszReaderNamesA, 0, NULL, NULL) < 1)
{ {
WLog_ERR(TAG, "ConvertFromUnicode failed"); length = ret->cBytes / 2;
return;
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 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; length = 0;
if (length > 2) if (length > 2)

View File

@ -452,10 +452,10 @@ void smartcard_scard_handle_native_to_redir(SMARTCARD_DEVICE* smartcard, REDIR_S
SCARDHANDLE hCard); SCARDHANDLE hCard);
LONG smartcard_unpack_common_type_header(SMARTCARD_DEVICE* smartcard, wStream* s); 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_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); UINT32 objectBufferLength);
LONG smartcard_unpack_redir_scard_context(SMARTCARD_DEVICE* smartcard, wStream* s, LONG smartcard_unpack_redir_scard_context(SMARTCARD_DEVICE* smartcard, wStream* s,

View File

@ -476,43 +476,29 @@ BOOL freerdp_client_add_device_channel(rdpSettings* settings, int count,
settings->RedirectSmartCards = TRUE; settings->RedirectSmartCards = TRUE;
settings->DeviceRedirection = 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->Name = _strdup(params[1])))
if (!smartcard)
return FALSE;
smartcard->Type = RDPDR_DTYP_SMARTCARD;
if (count > 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); free(smartcard);
return FALSE; return FALSE;
} }
} }
if (!freerdp_device_collection_add(settings, (RDPDR_DEVICE*) smartcard))
{
free(smartcard->Name);
free(smartcard);
return FALSE;
}
return TRUE; return TRUE;
} }
else if (strcmp(params[0], "serial") == 0) else if (strcmp(params[0], "serial") == 0)

View File

@ -446,7 +446,6 @@ struct _RDPDR_SMARTCARD
UINT32 Id; UINT32 Id;
UINT32 Type; UINT32 Type;
char* Name; char* Name;
char* Path;
}; };
typedef struct _RDPDR_SMARTCARD RDPDR_SMARTCARD; typedef struct _RDPDR_SMARTCARD RDPDR_SMARTCARD;

View File

@ -307,17 +307,8 @@ out_print_name_error:
goto out_smartc_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; return (RDPDR_DEVICE*) _smartcard;
out_smartc_path_error:
free(_smartcard->Name);
out_smartc_name_error: out_smartc_name_error:
free(_smartcard); free(_smartcard);
return NULL; return NULL;
@ -428,7 +419,7 @@ void freerdp_device_collection_free(rdpSettings* settings)
} }
else if (settings->DeviceArray[index]->Type == RDPDR_DTYP_SMARTCARD) else if (settings->DeviceArray[index]->Type == RDPDR_DTYP_SMARTCARD)
{ {
free(((RDPDR_SMARTCARD*) device)->Path);
} }
else if (settings->DeviceArray[index]->Type == RDPDR_DTYP_SERIAL) else if (settings->DeviceArray[index]->Type == RDPDR_DTYP_SERIAL)
{ {

View File

@ -789,8 +789,6 @@ WINSCARDAPI LONG WINAPI SCardListReadersWithDeviceInstanceIdW(SCARDCONTEXT hCont
WINSCARDAPI LONG WINAPI SCardAudit(SCARDCONTEXT hContext, DWORD dwEvent); WINSCARDAPI LONG WINAPI SCardAudit(SCARDCONTEXT hContext, DWORD dwEvent);
WINSCARDAPI LONG WINAPI SCardAddReaderName(HANDLE* key, LPSTR readerName);
#ifdef UNICODE #ifdef UNICODE
#define SCardListReaderGroups SCardListReaderGroupsW #define SCardListReaderGroups SCardListReaderGroupsW
#define SCardListReaders SCardListReadersW #define SCardListReaders SCardListReadersW
@ -1045,8 +1043,6 @@ typedef LONG(WINAPI* fnSCardListReadersWithDeviceInstanceIdW)(SCARDCONTEXT hCont
typedef LONG(WINAPI* fnSCardAudit)(SCARDCONTEXT hContext, DWORD dwEvent); typedef LONG(WINAPI* fnSCardAudit)(SCARDCONTEXT hContext, DWORD dwEvent);
typedef LONG(WINAPI* fnSCardAddReaderName)(HANDLE* key, LPSTR readerName);
struct _SCardApiFunctionTable struct _SCardApiFunctionTable
{ {
DWORD dwVersion; DWORD dwVersion;
@ -1128,7 +1124,6 @@ struct _SCardApiFunctionTable
fnSCardListReadersWithDeviceInstanceIdA pfnSCardListReadersWithDeviceInstanceIdA; fnSCardListReadersWithDeviceInstanceIdA pfnSCardListReadersWithDeviceInstanceIdA;
fnSCardListReadersWithDeviceInstanceIdW pfnSCardListReadersWithDeviceInstanceIdW; fnSCardListReadersWithDeviceInstanceIdW pfnSCardListReadersWithDeviceInstanceIdW;
fnSCardAudit pfnSCardAudit; fnSCardAudit pfnSCardAudit;
fnSCardAddReaderName pfnSCardAddReaderName;
}; };
typedef struct _SCardApiFunctionTable SCardApiFunctionTable; typedef struct _SCardApiFunctionTable SCardApiFunctionTable;

View File

@ -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_revision(void);
WINPR_API const char* winpr_get_build_config(void); WINPR_API const char* winpr_get_build_config(void);
#define WINPR_UNUSED(x) (void)(x)
#endif /* WINPR_H */ #endif /* WINPR_H */

View File

@ -507,11 +507,6 @@ WINSCARDAPI LONG WINAPI SCardAudit(SCARDCONTEXT hContext, DWORD dwEvent)
SCARDAPI_STUB_CALL_LONG(SCardAudit, hContext, 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 * Extended API
*/ */

File diff suppressed because it is too large Load Diff

View File

@ -155,7 +155,6 @@ struct _PCSCFunctionTable
PCSC_LPDWORD pcbAttrLen); PCSC_LPDWORD pcbAttrLen);
PCSC_LONG(* pfnSCardSetAttrib)(SCARDHANDLE hCard, PCSC_DWORD dwAttrId, LPCBYTE pbAttr, PCSC_LONG(* pfnSCardSetAttrib)(SCARDHANDLE hCard, PCSC_DWORD dwAttrId, LPCBYTE pbAttr,
PCSC_DWORD cbAttrLen); PCSC_DWORD cbAttrLen);
PCSC_LONG(* pfnSCardAddReaderName)(HANDLE* key, LPSTR readerName);
}; };
typedef struct _PCSCFunctionTable PCSCFunctionTable; typedef struct _PCSCFunctionTable PCSCFunctionTable;

View File

@ -111,8 +111,7 @@ SCardApiFunctionTable WinSCard_SCardApiFunctionTable =
NULL, /* SCardGetReaderDeviceInstanceIdW */ NULL, /* SCardGetReaderDeviceInstanceIdW */
NULL, /* SCardListReadersWithDeviceInstanceIdA */ NULL, /* SCardListReadersWithDeviceInstanceIdA */
NULL, /* SCardListReadersWithDeviceInstanceIdW */ NULL, /* SCardListReadersWithDeviceInstanceIdW */
NULL, /* SCardAudit */ NULL /* SCardAudit */
NULL /* SCardAddReaderName */
}; };
PSCardApiFunctionTable WinSCard_GetSCardApiFunctionTable(void) PSCardApiFunctionTable WinSCard_GetSCardApiFunctionTable(void)

View 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;
}