diff --git a/channels/smartcard/client/smartcard_main.c b/channels/smartcard/client/smartcard_main.c index 0945206ec..6fb6b5a91 100644 --- a/channels/smartcard/client/smartcard_main.c +++ b/channels/smartcard/client/smartcard_main.c @@ -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); diff --git a/channels/smartcard/client/smartcard_main.h b/channels/smartcard/client/smartcard_main.h index 10cdb5038..845123458 100644 --- a/channels/smartcard/client/smartcard_main.h +++ b/channels/smartcard/client/smartcard_main.h @@ -110,9 +110,6 @@ struct _SMARTCARD_DEVICE { DEVICE device; - char* name; - char* path; - HANDLE thread; HANDLE StartedEvent; wMessageQueue* IrpQueue; diff --git a/channels/smartcard/client/smartcard_operations.c b/channels/smartcard/client/smartcard_operations.c index a34cc0b20..91f14a700 100644 --- a/channels/smartcard/client/smartcard_operations.c +++ b/channels/smartcard/client/smartcard_operations.c @@ -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; diff --git a/channels/smartcard/client/smartcard_pack.c b/channels/smartcard/client/smartcard_pack.c index 1f89d5431..c5d66c18e 100644 --- a/channels/smartcard/client/smartcard_pack.c +++ b/channels/smartcard/client/smartcard_pack.c @@ -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) diff --git a/channels/smartcard/client/smartcard_pack.h b/channels/smartcard/client/smartcard_pack.h index 19c0954c1..f7bc08340 100644 --- a/channels/smartcard/client/smartcard_pack.h +++ b/channels/smartcard/client/smartcard_pack.h @@ -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, diff --git a/client/common/cmdline.c b/client/common/cmdline.c index 6db75b97f..17c3c16c2 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -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) diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index 2e1f79668..3bbf536d2 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -446,7 +446,6 @@ struct _RDPDR_SMARTCARD UINT32 Id; UINT32 Type; char* Name; - char* Path; }; typedef struct _RDPDR_SMARTCARD RDPDR_SMARTCARD; diff --git a/libfreerdp/common/settings.c b/libfreerdp/common/settings.c index 76d2439f4..9bf72a435 100644 --- a/libfreerdp/common/settings.c +++ b/libfreerdp/common/settings.c @@ -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) { diff --git a/winpr/include/winpr/smartcard.h b/winpr/include/winpr/smartcard.h index 8b52beb77..d168f2d90 100644 --- a/winpr/include/winpr/smartcard.h +++ b/winpr/include/winpr/smartcard.h @@ -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; diff --git a/winpr/include/winpr/winpr.h b/winpr/include/winpr/winpr.h index cafd692a9..9961e985e 100644 --- a/winpr/include/winpr/winpr.h +++ b/winpr/include/winpr/winpr.h @@ -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 */ diff --git a/winpr/libwinpr/smartcard/smartcard.c b/winpr/libwinpr/smartcard/smartcard.c index 2d2a8e55f..96ecc6f90 100644 --- a/winpr/libwinpr/smartcard/smartcard.c +++ b/winpr/libwinpr/smartcard/smartcard.c @@ -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 */ diff --git a/winpr/libwinpr/smartcard/smartcard_pcsc.c b/winpr/libwinpr/smartcard/smartcard_pcsc.c index 88910ba10..bbe8afbc6 100644 --- a/winpr/libwinpr/smartcard/smartcard_pcsc.c +++ b/winpr/libwinpr/smartcard/smartcard_pcsc.c @@ -28,15 +28,14 @@ #include #include #include +#include +#include #endif #include #include -#include -#include #include -#include #include #include #include @@ -130,13 +129,6 @@ struct _PCSC_SCARDHANDLE SCARDCONTEXT hSharedContext; }; -struct _PCSC_READER -{ - char* namePCSC; - char* nameWinSCard; -}; -typedef struct _PCSC_READER PCSC_READER; - static HMODULE g_PCSCModule = NULL; static PCSCFunctionTable g_PCSC = { 0 }; @@ -152,17 +144,12 @@ static unsigned int OSXVersion = 0; -static wArrayList* g_Readers = NULL; static wListDictionary* g_CardHandles = NULL; static wListDictionary* g_CardContexts = NULL; static wListDictionary* g_MemoryBlocks = NULL; -static wListDictionary* g_ReadersNames = NULL; char SMARTCARD_PNP_NOTIFICATION_A[] = "\\\\?PnP?\\Notification"; -WCHAR SMARTCARD_PNP_NOTIFICATION_W[] = -{ '\\', '\\', '?', 'P', 'n', 'P', '?', '\\', 'N', 'o', 't', 'i', 'f', 'i', 'c', 'a', 't', 'i', 'o', 'n', '\0' }; - const PCSC_SCARD_IO_REQUEST g_PCSC_rgSCardT0Pci = { SCARD_PROTOCOL_T0, sizeof(PCSC_SCARD_IO_REQUEST) }; const PCSC_SCARD_IO_REQUEST g_PCSC_rgSCardT1Pci = { SCARD_PROTOCOL_T1, sizeof(PCSC_SCARD_IO_REQUEST) }; const PCSC_SCARD_IO_REQUEST g_PCSC_rgSCardRawPci = { PCSC_SCARD_PROTOCOL_RAW, sizeof(PCSC_SCARD_IO_REQUEST) }; @@ -172,7 +159,7 @@ WINSCARDAPI LONG WINAPI PCSC_SCardEstablishContext_Internal(DWORD dwScope, LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext); WINSCARDAPI LONG WINAPI PCSC_SCardReleaseContext_Internal(SCARDCONTEXT hContext); -LONG PCSC_MapErrorCodeToWinSCard(LONG errorCode) +static LONG PCSC_MapErrorCodeToWinSCard(LONG errorCode) { /** * pcsc-lite returns SCARD_E_UNEXPECTED when it @@ -188,7 +175,7 @@ LONG PCSC_MapErrorCodeToWinSCard(LONG errorCode) return errorCode; } -DWORD PCSC_ConvertCardStateToWinSCard(DWORD dwCardState, LONG status) +static DWORD PCSC_ConvertCardStateToWinSCard(DWORD dwCardState, LONG status) { /** * pcsc-lite's SCardStatus returns a bit-field, not an enumerated value. @@ -236,7 +223,7 @@ DWORD PCSC_ConvertCardStateToWinSCard(DWORD dwCardState, LONG status) return SCARD_UNKNOWN; } -DWORD PCSC_ConvertProtocolsToWinSCard(DWORD dwProtocols) +static DWORD PCSC_ConvertProtocolsToWinSCard(DWORD dwProtocols) { /** * pcsc-lite uses a different value for SCARD_PROTOCOL_RAW, @@ -256,7 +243,7 @@ DWORD PCSC_ConvertProtocolsToWinSCard(DWORD dwProtocols) return dwProtocols; } -DWORD PCSC_ConvertProtocolsFromWinSCard(DWORD dwProtocols) +static DWORD PCSC_ConvertProtocolsFromWinSCard(DWORD dwProtocols) { /** * pcsc-lite uses a different value for SCARD_PROTOCOL_RAW, @@ -281,16 +268,7 @@ DWORD PCSC_ConvertProtocolsFromWinSCard(DWORD dwProtocols) return dwProtocols; } -void PCSC_ReaderAliasFree(PCSC_READER* reader) -{ - if (!reader) - return; - - free(reader->namePCSC); - free(reader->nameWinSCard); -} - -PCSC_SCARDCONTEXT* PCSC_GetCardContextData(SCARDCONTEXT hContext) +static PCSC_SCARDCONTEXT* PCSC_GetCardContextData(SCARDCONTEXT hContext) { PCSC_SCARDCONTEXT* pContext; @@ -305,7 +283,7 @@ PCSC_SCARDCONTEXT* PCSC_GetCardContextData(SCARDCONTEXT hContext) return pContext; } -PCSC_SCARDCONTEXT* PCSC_EstablishCardContext(SCARDCONTEXT hContext) +static PCSC_SCARDCONTEXT* PCSC_EstablishCardContext(SCARDCONTEXT hContext) { PCSC_SCARDCONTEXT* pContext; pContext = (PCSC_SCARDCONTEXT*) calloc(1, sizeof(PCSC_SCARDCONTEXT)); @@ -326,16 +304,6 @@ PCSC_SCARDCONTEXT* PCSC_EstablishCardContext(SCARDCONTEXT hContext) goto errors; } - if (!g_Readers) - { - g_Readers = ArrayList_New(TRUE); - - if (!g_Readers) - goto errors; - - ArrayList_Object(g_Readers)->fnObjectFree = (OBJECT_FREE_FN) PCSC_ReaderAliasFree; - } - if (!ListDictionary_Add(g_CardContexts, (void*) hContext, (void*) pContext)) goto errors; @@ -347,7 +315,7 @@ error_spinlock: return NULL; } -void PCSC_ReleaseCardContext(SCARDCONTEXT hContext) +static void PCSC_ReleaseCardContext(SCARDCONTEXT hContext) { PCSC_SCARDCONTEXT* pContext; pContext = PCSC_GetCardContextData(hContext); @@ -367,7 +335,7 @@ void PCSC_ReleaseCardContext(SCARDCONTEXT hContext) ListDictionary_Remove(g_CardContexts, (void*) hContext); } -BOOL PCSC_LockCardContext(SCARDCONTEXT hContext) +static BOOL PCSC_LockCardContext(SCARDCONTEXT hContext) { PCSC_SCARDCONTEXT* pContext; pContext = PCSC_GetCardContextData(hContext); @@ -382,7 +350,7 @@ BOOL PCSC_LockCardContext(SCARDCONTEXT hContext) return TRUE; } -BOOL PCSC_UnlockCardContext(SCARDCONTEXT hContext) +static BOOL PCSC_UnlockCardContext(SCARDCONTEXT hContext) { PCSC_SCARDCONTEXT* pContext; pContext = PCSC_GetCardContextData(hContext); @@ -397,7 +365,7 @@ BOOL PCSC_UnlockCardContext(SCARDCONTEXT hContext) return TRUE; } -PCSC_SCARDHANDLE* PCSC_GetCardHandleData(SCARDHANDLE hCard) +static PCSC_SCARDHANDLE* PCSC_GetCardHandleData(SCARDHANDLE hCard) { PCSC_SCARDHANDLE* pCard; @@ -412,7 +380,7 @@ PCSC_SCARDHANDLE* PCSC_GetCardHandleData(SCARDHANDLE hCard) return pCard; } -SCARDCONTEXT PCSC_GetCardContextFromHandle(SCARDHANDLE hCard) +static SCARDCONTEXT PCSC_GetCardContextFromHandle(SCARDHANDLE hCard) { PCSC_SCARDHANDLE* pCard; pCard = PCSC_GetCardHandleData(hCard); @@ -423,7 +391,7 @@ SCARDCONTEXT PCSC_GetCardContextFromHandle(SCARDHANDLE hCard) return pCard->hSharedContext; } -BOOL PCSC_WaitForCardAccess(SCARDCONTEXT hContext, SCARDHANDLE hCard, BOOL shared) +static BOOL PCSC_WaitForCardAccess(SCARDCONTEXT hContext, SCARDHANDLE hCard, BOOL shared) { BOOL status = TRUE; PCSC_SCARDHANDLE* pCard = NULL; @@ -477,7 +445,7 @@ BOOL PCSC_WaitForCardAccess(SCARDCONTEXT hContext, SCARDHANDLE hCard, BOOL share return status; } -BOOL PCSC_ReleaseCardAccess(SCARDCONTEXT hContext, SCARDHANDLE hCard) +static BOOL PCSC_ReleaseCardAccess(SCARDCONTEXT hContext, SCARDHANDLE hCard) { PCSC_SCARDHANDLE* pCard = NULL; PCSC_SCARDCONTEXT* pContext = NULL; @@ -525,7 +493,7 @@ BOOL PCSC_ReleaseCardAccess(SCARDCONTEXT hContext, SCARDHANDLE hCard) return TRUE; } -PCSC_SCARDHANDLE* PCSC_ConnectCardHandle(SCARDCONTEXT hSharedContext, SCARDHANDLE hCard) +static PCSC_SCARDHANDLE* PCSC_ConnectCardHandle(SCARDCONTEXT hSharedContext, SCARDHANDLE hCard) { PCSC_SCARDHANDLE* pCard; PCSC_SCARDCONTEXT* pContext; @@ -562,7 +530,7 @@ error: return NULL; } -void PCSC_DisconnectCardHandle(SCARDHANDLE hCard) +static void PCSC_DisconnectCardHandle(SCARDHANDLE hCard) { PCSC_SCARDHANDLE* pCard; PCSC_SCARDCONTEXT* pContext; @@ -588,314 +556,7 @@ void PCSC_DisconnectCardHandle(SCARDHANDLE hCard) pContext->dwCardHandleCount--; } -char* PCSC_GetReaderNameFromAlias(char* nameWinSCard) -{ - int index; - int count; - PCSC_READER* reader; - char* namePCSC = NULL; - ArrayList_Lock(g_Readers); - count = ArrayList_Count(g_Readers); - - for (index = 0; index < count; index++) - { - reader = ArrayList_GetItem(g_Readers, index); - - if (strcmp(nameWinSCard, reader->nameWinSCard) == 0) - { - namePCSC = reader->namePCSC; - break; - } - } - - ArrayList_Unlock(g_Readers); - return namePCSC; -} - -BOOL PCSC_AddReaderNameAlias(char* namePCSC, char* nameWinSCard) -{ - PCSC_READER* reader; - - if (PCSC_GetReaderNameFromAlias(nameWinSCard)) - return TRUE; - - reader = (PCSC_READER*) calloc(1, sizeof(PCSC_READER)); - - if (!reader) - return FALSE; - - reader->namePCSC = _strdup(namePCSC); - - if (!reader->namePCSC) - goto error_namePSC; - - reader->nameWinSCard = _strdup(nameWinSCard); - - if (!reader->nameWinSCard) - goto error_nameWinSCard; - - if (ArrayList_Add(g_Readers, reader) < 0) - goto error_add; - - return TRUE; -error_add: - free(reader->nameWinSCard); -error_nameWinSCard: - free(reader->namePCSC); -error_namePSC: - free(reader); - return FALSE; -} - -char* PCSC_ConvertReaderNameToWinSCard(const char* name) -{ - int size; - int length; - int ctoken; - int ntokens; - char* p, *q; - char* tokens[64][2]; - char* nameWinSCard; - - /** - * pcsc-lite reader name format: - * name [interface] (serial) index slot - * - * Athena IDProtect Key v2 [Main Interface] 00 00 - * - * name: Athena IDProtect Key v2 - * interface: Main Interface - * serial: N/A - * index: 00 - * slot: 00 - * - * Athena ASE IIIe 00 00 - * - * name: Athena ASE IIIe - * interface: N/A - * serial: N/A - * index: 00 - * slot: 00 - * - * Athena ASE IIIe [CCID Bulk Interface] 00 00 - * - * name: Athena ASE IIIe - * interface: CCID Bulk Interface - * serial: N/A - * index: 00 - * slot: 00 - * - * Gemalto PC Twin Reader (944B4BF1) 00 00 - * - * name: Gemalto PC Twin Reader - * interface: N/A - * serial: 944B4BF1 - * index: 00 - * slot: 00 - * - * the serial component is optional - * the index is a two digit zero-padded integer - * the slot is a two digit zero-padded integer - */ - if (!name) - return NULL; - - memset(tokens, 0, sizeof(tokens)); - length = strlen(name); - - if (length < 10) - return NULL; - - ntokens = 0; - p = q = (char*) name; - - while (*p) - { - if (*p == ' ') - { - tokens[ntokens][0] = q; - tokens[ntokens][1] = p; - q = p + 1; - ntokens++; - } - - p++; - } - - tokens[ntokens][0] = q; - tokens[ntokens][1] = p; - ntokens++; - - if (ntokens < 2) - return NULL; - - ctoken = ntokens - 1; - p = tokens[0][0]; - q = tokens[ctoken][1]; - length = (q - p); - size = length + 16; - nameWinSCard = (char*) malloc(size); - - if (!nameWinSCard) - return NULL; - - sprintf_s(nameWinSCard, size, "%.*s", length, p); - return nameWinSCard; -} - -char* PCSC_GetReaderAliasFromName(char* namePCSC) -{ - char* nameWinSCard = NULL; - nameWinSCard = PCSC_ConvertReaderNameToWinSCard(namePCSC); - - if (nameWinSCard) - PCSC_AddReaderNameAlias(namePCSC, nameWinSCard); - - return nameWinSCard; -} - -int PCSC_RedirectReader(char* readerName) -{ - char* name; - ULONG_PTR* readers; - int i, nbReaders; - nbReaders = ListDictionary_GetKeys(g_ReadersNames, &readers); - - for (i = 0; i < nbReaders; i++) - { - name = ListDictionary_GetItemValue(g_ReadersNames, (void*) readers[i]); - - if (name) - { - if (strcmp(name, "") == 0) - { - return 1; - } - - if (strncmp(readerName, name, strlen(readerName)) == 0) - { - return 1; - } - } - else - { - return 2; - } - } - - return 0; -} - -char* PCSC_ConvertReaderNamesToWinSCard(const char* names, LPDWORD pcchReaders) -{ - int ret = 0; - int length; - char* p, *q; - DWORD cchReaders; - char* nameWinSCard; - char* namesWinSCard; - BOOL endReaderName = FALSE; - BOOL allReaders = FALSE; - p = (char*) names; - cchReaders = *pcchReaders; - namesWinSCard = (char*) calloc(cchReaders, 2); - - if (!namesWinSCard) - return NULL; - - q = namesWinSCard; - p = (char*) names; - - while ((p - names) < cchReaders) - { - nameWinSCard = PCSC_GetReaderAliasFromName(p); - - if (nameWinSCard) - { - length = strlen(nameWinSCard); - ret = PCSC_RedirectReader(nameWinSCard); - - if (ret == 1) - { - CopyMemory(q, nameWinSCard, length); - endReaderName = TRUE; - } - else if (ret == 2) - { - CopyMemory(q, nameWinSCard, length); - allReaders = TRUE; - } - - free(nameWinSCard); - } - else - { - length = strlen(p); - CopyMemory(q, p, length); - } - - if (endReaderName) - { - q += length; - *q = '\0'; - q++; - endReaderName = FALSE; - } - else if (allReaders) - { - q += length; - *q = '\0'; - q++; - } - - p += strlen(p) + 1; - } - - *q = '\0'; - q++; - *pcchReaders = (DWORD)(q - namesWinSCard); - return namesWinSCard; -} - -char* PCSC_ConvertReaderNamesToPCSC(const char* names, LPDWORD pcchReaders) -{ - int length; - char* p, *q; - char* namePCSC; - char* namesPCSC; - DWORD cchReaders; - p = (char*) names; - cchReaders = *pcchReaders; - namesPCSC = (char*) calloc(cchReaders, 2); - - if (!namesPCSC) - return NULL; - - q = namesPCSC; - p = (char*) names; - - while ((p - names) < cchReaders) - { - namePCSC = PCSC_GetReaderNameFromAlias(p); - - if (!namePCSC) - namePCSC = p; - - length = strlen(namePCSC); - CopyMemory(q, namePCSC, length); - q += length; - *q = '\0'; - q++; - p += strlen(p) + 1; - } - - *q = '\0'; - q++; - *pcchReaders = (DWORD)(q - namesPCSC); - return namesPCSC; -} - -BOOL PCSC_AddMemoryBlock(SCARDCONTEXT hContext, void* pvMem) +static BOOL PCSC_AddMemoryBlock(SCARDCONTEXT hContext, void* pvMem) { if (!g_MemoryBlocks) { @@ -908,31 +569,16 @@ BOOL PCSC_AddMemoryBlock(SCARDCONTEXT hContext, void* pvMem) return ListDictionary_Add(g_MemoryBlocks, pvMem, (void*) hContext); } -void* PCSC_RemoveMemoryBlock(SCARDCONTEXT hContext, void* pvMem) +static void* PCSC_RemoveMemoryBlock(SCARDCONTEXT hContext, void* pvMem) { + WINPR_UNUSED(hContext); + if (!g_MemoryBlocks) return NULL; return ListDictionary_Remove(g_MemoryBlocks, pvMem); } -void* PCSC_SCardAllocMemory(SCARDCONTEXT hContext, size_t size) -{ - void* pvMem; - pvMem = malloc(size); - - if (!pvMem) - return NULL; - - if (!PCSC_AddMemoryBlock(hContext, pvMem)) - { - free(pvMem); - return NULL; - } - - return pvMem; -} - /** * Standard Windows Smart Card API (PCSC) */ @@ -940,14 +586,14 @@ void* PCSC_SCardAllocMemory(SCARDCONTEXT hContext, size_t size) WINSCARDAPI LONG WINAPI PCSC_SCardEstablishContext_Internal(DWORD dwScope, LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext) { + WINPR_UNUSED(dwScope); /* SCARD_SCOPE_SYSTEM is the only scope supported by pcsc-lite */ LONG status = SCARD_S_SUCCESS; - PCSC_DWORD pcsc_dwScope = (PCSC_DWORD) dwScope; if (!g_PCSC.pfnSCardEstablishContext) return SCARD_E_NO_SERVICE; - pcsc_dwScope = SCARD_SCOPE_SYSTEM; /* this is the only scope supported by pcsc-lite */ - status = (LONG) g_PCSC.pfnSCardEstablishContext(pcsc_dwScope, pvReserved1, pvReserved2, phContext); + status = (LONG) g_PCSC.pfnSCardEstablishContext(SCARD_SCOPE_SYSTEM, pvReserved1, pvReserved2, + phContext); status = PCSC_MapErrorCodeToWinSCard(status); return status; } @@ -955,7 +601,7 @@ WINSCARDAPI LONG WINAPI PCSC_SCardEstablishContext_Internal(DWORD dwScope, WINSCARDAPI LONG WINAPI PCSC_SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext) { - LONG status = SCARD_S_SUCCESS; + LONG status; status = PCSC_SCardEstablishContext_Internal(dwScope, pvReserved1, pvReserved2, phContext); if (status == SCARD_S_SUCCESS) @@ -1009,7 +655,6 @@ WINSCARDAPI LONG WINAPI PCSC_SCardListReaderGroups_Internal(SCARDCONTEXT hContex LPSTR mszGroups, LPDWORD pcchGroups) { LONG status = SCARD_S_SUCCESS; - char* mszGroupsWinSCard = NULL; BOOL pcchGroupsAlloc = FALSE; LPSTR* pMszGroups = (LPSTR*) mszGroups; PCSC_DWORD pcsc_cchGroups = 0; @@ -1052,19 +697,6 @@ WINSCARDAPI LONG WINAPI PCSC_SCardListReaderGroups_Internal(SCARDCONTEXT hContex status = PCSC_MapErrorCodeToWinSCard(status); *pcchGroups = (DWORD) pcsc_cchGroups; - - if (status == SCARD_S_SUCCESS) - { - mszGroupsWinSCard = PCSC_ConvertReaderNamesToWinSCard(*pMszGroups, pcchGroups); - - if (mszGroupsWinSCard) - { - PCSC_SCardFreeMemory_Internal(hContext, *pMszGroups); - *pMszGroups = mszGroupsWinSCard; - PCSC_AddMemoryBlock(hContext, *pMszGroups); - } - } - return status; } @@ -1119,7 +751,6 @@ WINSCARDAPI LONG WINAPI PCSC_SCardListReaders_Internal(SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders, LPDWORD pcchReaders) { LONG status = SCARD_S_SUCCESS; - char* mszReadersWinSCard = NULL; BOOL pcchReadersAlloc = FALSE; LPSTR* pMszReaders = (LPSTR*) mszReaders; PCSC_DWORD pcsc_cchReaders = 0; @@ -1164,19 +795,6 @@ WINSCARDAPI LONG WINAPI PCSC_SCardListReaders_Internal(SCARDCONTEXT hContext, status = PCSC_MapErrorCodeToWinSCard(status); *pcchReaders = (DWORD) pcsc_cchReaders; - - if (status == SCARD_S_SUCCESS) - { - mszReadersWinSCard = PCSC_ConvertReaderNamesToWinSCard(*pMszReaders, pcchReaders); - - if (mszReadersWinSCard) - { - PCSC_SCardFreeMemory_Internal(hContext, *pMszReaders); - *pMszReaders = mszReadersWinSCard; - PCSC_AddMemoryBlock(hContext, *pMszReaders); - } - } - return status; } @@ -1534,8 +1152,6 @@ WINSCARDAPI LONG WINAPI PCSC_SCardGetStatusChange_Internal(SCARDCONTEXT hContext { int i, j; int* map; - DWORD dwEventState; - BOOL stateChanged = FALSE; PCSC_DWORD cMappedReaders; PCSC_SCARD_READERSTATE* states; LONG status = SCARD_S_SUCCESS; @@ -1580,7 +1196,7 @@ WINSCARDAPI LONG WINAPI PCSC_SCardGetStatusChange_Internal(SCARDCONTEXT hContext { if (!g_PnP_Notification) { - if (strcmp(rgReaderStates[i].szReader, SMARTCARD_PNP_NOTIFICATION_A) == 0) + if (0 == _stricmp(rgReaderStates[i].szReader, SMARTCARD_PNP_NOTIFICATION_A)) { map[i] = -1; /* unmapped */ continue; @@ -1588,11 +1204,7 @@ WINSCARDAPI LONG WINAPI PCSC_SCardGetStatusChange_Internal(SCARDCONTEXT hContext } map[i] = j; - states[j].szReader = PCSC_GetReaderNameFromAlias((char*) rgReaderStates[i].szReader); - - if (!states[j].szReader) - states[j].szReader = rgReaderStates[i].szReader; - + states[j].szReader = rgReaderStates[i].szReader; states[j].dwCurrentState = rgReaderStates[i].dwCurrentState; states[j].pvUserData = rgReaderStates[i].pvUserData; states[j].dwEventState = rgReaderStates[i].dwEventState; @@ -1623,37 +1235,11 @@ WINSCARDAPI LONG WINAPI PCSC_SCardGetStatusChange_Internal(SCARDCONTEXT hContext rgReaderStates[i].dwCurrentState = states[j].dwCurrentState; rgReaderStates[i].cbAtr = states[j].cbAtr; CopyMemory(&(rgReaderStates[i].rgbAtr), &(states[j].rgbAtr), PCSC_MAX_ATR_SIZE); - dwEventState = states[j].dwEventState & ~SCARD_STATE_CHANGED; - - if (dwEventState != rgReaderStates[i].dwCurrentState) - { - rgReaderStates[i].dwEventState = states[j].dwEventState; - - if (dwEventState & SCARD_STATE_PRESENT) - { - if (!(dwEventState & SCARD_STATE_EXCLUSIVE)) - rgReaderStates[i].dwEventState |= SCARD_STATE_INUSE; - } - - stateChanged = TRUE; - } - else - { - rgReaderStates[i].dwEventState = dwEventState; - } - - if (rgReaderStates[i].dwCurrentState & SCARD_STATE_IGNORE) - rgReaderStates[i].dwEventState = SCARD_STATE_IGNORE; + rgReaderStates[i].dwEventState = states[j].dwEventState; } free(map); free(states); - - if ((status == SCARD_S_SUCCESS) && !stateChanged) - status = SCARD_E_TIMEOUT; - else if ((status == SCARD_E_TIMEOUT) && stateChanged) - return SCARD_S_SUCCESS; - return status; } @@ -1743,7 +1329,6 @@ WINSCARDAPI LONG WINAPI PCSC_SCardConnect_Internal(SCARDCONTEXT hContext, LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol) { BOOL shared; - BOOL access; char* szReaderPCSC; LONG status = SCARD_S_SUCCESS; PCSC_SCARDHANDLE* pCard = NULL; @@ -1755,11 +1340,8 @@ WINSCARDAPI LONG WINAPI PCSC_SCardConnect_Internal(SCARDCONTEXT hContext, return SCARD_E_NO_SERVICE; shared = (dwShareMode == SCARD_SHARE_DIRECT) ? TRUE : FALSE; - access = PCSC_WaitForCardAccess(hContext, 0, shared); - szReaderPCSC = PCSC_GetReaderNameFromAlias((char*) szReader); - - if (!szReaderPCSC) - szReaderPCSC = (char*) szReader; + PCSC_WaitForCardAccess(hContext, 0, shared); + szReaderPCSC = (char*) szReader; /** * As stated here : https://pcsclite.alioth.debian.org/api/group__API.html#ga4e515829752e0a8dbc4d630696a8d6a5 @@ -1831,7 +1413,6 @@ WINSCARDAPI LONG WINAPI PCSC_SCardReconnect(SCARDHANDLE hCard, DWORD dwShareMode, DWORD dwPreferredProtocols, DWORD dwInitialization, LPDWORD pdwActiveProtocol) { BOOL shared; - BOOL access; LONG status = SCARD_S_SUCCESS; PCSC_DWORD pcsc_dwShareMode = (PCSC_DWORD) dwShareMode; PCSC_DWORD pcsc_dwPreferredProtocols = 0; @@ -1842,7 +1423,7 @@ WINSCARDAPI LONG WINAPI PCSC_SCardReconnect(SCARDHANDLE hCard, return SCARD_E_NO_SERVICE; shared = (dwShareMode == SCARD_SHARE_DIRECT) ? TRUE : FALSE; - access = PCSC_WaitForCardAccess(0, hCard, shared); + PCSC_WaitForCardAccess(0, hCard, shared); pcsc_dwPreferredProtocols = (PCSC_DWORD) PCSC_ConvertProtocolsFromWinSCard(dwPreferredProtocols); status = (LONG) g_PCSC.pfnSCardReconnect(hCard, pcsc_dwShareMode, pcsc_dwPreferredProtocols, pcsc_dwInitialization, &pcsc_dwActiveProtocol); @@ -1975,22 +1556,27 @@ WINSCARDAPI LONG WINAPI PCSC_SCardState(SCARDHANDLE hCard, return status; } +/* + * PCSC returns a string but Windows SCardStatus requires the return to be a multi string. + * Therefore extra length checks and additional buffer allocation is required + */ WINSCARDAPI LONG WINAPI PCSC_SCardStatus_Internal(SCARDHANDLE hCard, LPSTR mszReaderNames, LPDWORD pcchReaderLen, LPDWORD pdwState, - LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen) + LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen, BOOL unicode) { - SCARDCONTEXT hContext; - char* mszReaderNamesWinSCard = NULL; - BOOL pcbAtrLenAlloc = FALSE; - BOOL pcchReaderLenAlloc = FALSE; - LPBYTE* pPbAtr = (LPBYTE*) pbAtr; - LPSTR* pMszReaderNames = (LPSTR*) mszReaderNames; - LONG status = SCARD_S_SUCCESS; PCSC_SCARDHANDLE* pCard = NULL; + SCARDCONTEXT hContext; + LONG status; PCSC_DWORD pcsc_cchReaderLen = 0; + PCSC_DWORD pcsc_cbAtrLen = 0; PCSC_DWORD pcsc_dwState = 0; PCSC_DWORD pcsc_dwProtocol = 0; - PCSC_DWORD pcsc_cbAtrLen = 0; + BOOL allocateReader = FALSE; + BOOL allocateAtr = FALSE; + LPSTR readerNames = mszReaderNames; + LPBYTE atr = pbAtr; + LPSTR tReader = NULL; + LPBYTE tATR = NULL; if (!g_PCSC.pfnSCardStatus) return SCARD_E_NO_SERVICE; @@ -2003,109 +1589,142 @@ WINSCARDAPI LONG WINAPI PCSC_SCardStatus_Internal(SCARDHANDLE hCard, PCSC_WaitForCardAccess(0, hCard, pCard->shared); hContext = PCSC_GetCardContextFromHandle(hCard); - if (!hContext || !pcchReaderLen || !pdwState || !pdwProtocol || !pcbAtrLen) + if (!hContext) return SCARD_E_INVALID_VALUE; - if (*pcchReaderLen == SCARD_AUTOALLOCATE) - pcchReaderLenAlloc = TRUE; + status = (LONG) g_PCSC.pfnSCardStatus(hCard, NULL, &pcsc_cchReaderLen, NULL, NULL, NULL, + &pcsc_cbAtrLen); - pcsc_cchReaderLen = pcchReaderLenAlloc ? PCSC_SCARD_AUTOALLOCATE : (PCSC_DWORD) * pcchReaderLen; + if (status != STATUS_SUCCESS) + return PCSC_MapErrorCodeToWinSCard(status); - if (*pcbAtrLen == SCARD_AUTOALLOCATE) - pcbAtrLenAlloc = TRUE; + pcsc_cchReaderLen++; - pcsc_cbAtrLen = pcbAtrLenAlloc ? PCSC_SCARD_AUTOALLOCATE : (PCSC_DWORD) * pcbAtrLen; + if (unicode) + pcsc_cchReaderLen *= 2; - if ((pcchReaderLenAlloc || pcbAtrLenAlloc) && !g_SCardAutoAllocate) + if (pcchReaderLen) { - if (pcchReaderLenAlloc) - pcsc_cchReaderLen = 0; + if (*pcchReaderLen == SCARD_AUTOALLOCATE) + allocateReader = TRUE; + else if (mszReaderNames && (*pcchReaderLen < pcsc_cchReaderLen)) + return SCARD_E_INSUFFICIENT_BUFFER; + else + pcsc_cchReaderLen = *pcchReaderLen; + } - if (pcbAtrLenAlloc) - pcsc_cbAtrLen = 0; + if (pcbAtrLen) + { + if (*pcbAtrLen == SCARD_AUTOALLOCATE) + allocateAtr = TRUE; + else if (pbAtr && (*pcbAtrLen < pcsc_cbAtrLen)) + return SCARD_E_INSUFFICIENT_BUFFER; + else + pcsc_cbAtrLen = *pcbAtrLen; + } - status = (LONG) g_PCSC.pfnSCardStatus(hCard, - (pcchReaderLenAlloc) ? NULL : mszReaderNames, &pcsc_cchReaderLen, - &pcsc_dwState, &pcsc_dwProtocol, - (pcbAtrLenAlloc) ? NULL : pbAtr, &pcsc_cbAtrLen); - - if (status == SCARD_S_SUCCESS) - { - if (pcchReaderLenAlloc) - { + if (allocateReader && pcsc_cchReaderLen > 0 && mszReaderNames) + { #ifdef __MACOSX__ - /** - * Workaround for SCardStatus Bug in MAC OS X Yosemite - */ - if (OSXVersion == 0x10100000) - pcsc_cchReaderLen++; + /** + * Workaround for SCardStatus Bug in MAC OS X Yosemite + */ + if (OSXVersion == 0x10100000) + pcsc_cchReaderLen++; #endif - *pMszReaderNames = (LPSTR) calloc(1, pcsc_cchReaderLen); + tReader = calloc(1, pcsc_cchReaderLen); - if (!*pMszReaderNames) - return SCARD_E_NO_MEMORY; - } - - if (pcbAtrLenAlloc) - { - *pPbAtr = (BYTE*) calloc(1, pcsc_cbAtrLen); - - if (!*pPbAtr) - return SCARD_E_NO_MEMORY; - } - - status = (LONG) g_PCSC.pfnSCardStatus(hCard, - *pMszReaderNames, &pcsc_cchReaderLen, - &pcsc_dwState, &pcsc_dwProtocol, - pbAtr, &pcsc_cbAtrLen); - - if (status != SCARD_S_SUCCESS) - { - if (pcchReaderLenAlloc) - { - free(*pMszReaderNames); - *pMszReaderNames = NULL; - } - - if (pcbAtrLenAlloc) - { - free(*pPbAtr); - *pPbAtr = NULL; - } - } - else - { - if (pcchReaderLenAlloc) - PCSC_AddMemoryBlock(hContext, *pMszReaderNames); - - if (pcbAtrLenAlloc) - PCSC_AddMemoryBlock(hContext, *pPbAtr); - } + if (!tReader) + { + status = ERROR_NOT_ENOUGH_MEMORY; + goto out_fail; } - } - else - { - status = (LONG) g_PCSC.pfnSCardStatus(hCard, mszReaderNames, &pcsc_cchReaderLen, - &pcsc_dwState, &pcsc_dwProtocol, pbAtr, &pcsc_cbAtrLen); + + readerNames = tReader; } - status = PCSC_MapErrorCodeToWinSCard(status); - *pcchReaderLen = (DWORD) pcsc_cchReaderLen; - mszReaderNamesWinSCard = PCSC_ConvertReaderNamesToWinSCard(*pMszReaderNames, pcchReaderLen); - - if (mszReaderNamesWinSCard) + if (allocateAtr && pcsc_cbAtrLen > 0 && pbAtr) { - PCSC_SCardFreeMemory_Internal(hContext, *pMszReaderNames); - *pMszReaderNames = mszReaderNamesWinSCard; - PCSC_AddMemoryBlock(hContext, *pMszReaderNames); + tATR = calloc(1, pcsc_cbAtrLen); + + if (!tATR) + { + status = ERROR_NOT_ENOUGH_MEMORY; + goto out_fail; + } + + atr = tATR; + } + + status = (LONG) g_PCSC.pfnSCardStatus(hCard, readerNames, &pcsc_cchReaderLen, &pcsc_dwState, + &pcsc_dwProtocol, atr, + &pcsc_cbAtrLen); + + if (status != STATUS_SUCCESS) + goto out_fail; + + if (tATR) + { + PCSC_AddMemoryBlock(hContext, tATR); + *(LPBYTE*)pbAtr = tATR; + } + + if (tReader) + { + if (unicode) + { + LPSTR mszReaderNamesW = NULL; + int pcsc_cchReaderLenW = 0; + pcsc_cchReaderLenW = ConvertToUnicode(CP_UTF8, 0, tReader, *pcchReaderLen, + (WCHAR**) &mszReaderNamesW, 0); + + if (pcsc_cchReaderLenW <= 0 || mszReaderNamesW == NULL) + { + status = ERROR_NOT_ENOUGH_MEMORY; + goto out_fail; + } + + readerNames = mszReaderNamesW; + free(tReader); + PCSC_AddMemoryBlock(hContext, mszReaderNamesW); + *(LPSTR*) mszReaderNames = mszReaderNamesW; + } + else + { + PCSC_AddMemoryBlock(hContext, tReader); + *(LPSTR*) mszReaderNames = tReader; + } } pcsc_dwState &= 0xFFFF; - *pdwState = PCSC_ConvertCardStateToWinSCard((DWORD) pcsc_dwState, status); - *pdwProtocol = PCSC_ConvertProtocolsToWinSCard((DWORD) pcsc_dwProtocol); - *pcbAtrLen = (DWORD) pcsc_cbAtrLen; + + if (pdwState) + *pdwState = PCSC_ConvertCardStateToWinSCard((DWORD) pcsc_dwState, status); + + if (pdwProtocol) + *pdwProtocol = PCSC_ConvertProtocolsToWinSCard((DWORD) pcsc_dwProtocol); + + if (pcbAtrLen) + *pcbAtrLen = (DWORD) pcsc_cbAtrLen; + + if (pcchReaderLen) + { + if (unicode) + *pcchReaderLen = (pcsc_cchReaderLen + 1) * 2; + else + *pcchReaderLen = pcsc_cchReaderLen + 1; + } + + /* Make sure the last byte is set */ + if (readerNames) + readerNames[pcsc_cchReaderLen] = '\0'; + + return status; +out_fail: + free(tReader); + free(tATR); return status; } @@ -2113,40 +1732,16 @@ WINSCARDAPI LONG WINAPI PCSC_SCardStatusA(SCARDHANDLE hCard, LPSTR mszReaderNames, LPDWORD pcchReaderLen, LPDWORD pdwState, LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen) { - LONG status = SCARD_S_SUCCESS; - status = PCSC_SCardStatus_Internal(hCard, mszReaderNames, pcchReaderLen, pdwState, pdwProtocol, - pbAtr, pcbAtrLen); - return status; + return PCSC_SCardStatus_Internal(hCard, mszReaderNames, pcchReaderLen, pdwState, pdwProtocol, + pbAtr, pcbAtrLen, FALSE); } WINSCARDAPI LONG WINAPI PCSC_SCardStatusW(SCARDHANDLE hCard, LPWSTR mszReaderNames, LPDWORD pcchReaderLen, LPDWORD pdwState, LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen) { - SCARDCONTEXT hContext = 0; - LPSTR mszReaderNamesA = NULL; - LONG status = SCARD_S_SUCCESS; - - if (!g_PCSC.pfnSCardStatus) - return SCARD_E_NO_SERVICE; - - hContext = PCSC_GetCardContextFromHandle(hCard); - - if (!hContext) - return SCARD_E_INVALID_VALUE; - - status = PCSC_SCardStatus_Internal(hCard, (LPSTR) &mszReaderNamesA, pcchReaderLen, pdwState, - pdwProtocol, pbAtr, pcbAtrLen); - - if (mszReaderNamesA) - { - *pcchReaderLen = ConvertToUnicode(CP_UTF8, 0, mszReaderNamesA, *pcchReaderLen, - (WCHAR**) mszReaderNames, 0); - PCSC_AddMemoryBlock(hContext, mszReaderNames); - PCSC_SCardFreeMemory_Internal(hContext, mszReaderNamesA); - } - - return status; + return PCSC_SCardStatus_Internal(hCard, (LPSTR) mszReaderNames, pcchReaderLen, pdwState, + pdwProtocol, pbAtr, pcbAtrLen, TRUE); } WINSCARDAPI LONG WINAPI PCSC_SCardTransmit(SCARDHANDLE hCard, @@ -2261,6 +1856,7 @@ WINSCARDAPI LONG WINAPI PCSC_SCardTransmit(SCARDHANDLE hCard, WINSCARDAPI LONG WINAPI PCSC_SCardGetTransmitCount(SCARDHANDLE hCard, LPDWORD pcTransmitCount) { + WINPR_UNUSED(pcTransmitCount); PCSC_SCARDHANDLE* pCard = NULL; pCard = PCSC_GetCardHandleData(hCard); @@ -2416,7 +2012,6 @@ WINSCARDAPI LONG WINAPI PCSC_SCardGetAttrib_FriendlyName(SCARDHANDLE hCard, DWOR { int length = 0; char* namePCSC = NULL; - char* nameWinSCard; DWORD cbAttrLen = 0; char* pbAttrA = NULL; WCHAR* pbAttrW = NULL; @@ -2445,8 +2040,8 @@ WINSCARDAPI LONG WINAPI PCSC_SCardGetAttrib_FriendlyName(SCARDHANDLE hCard, DWOR if (status != SCARD_S_SUCCESS) return status; - length = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) pbAttrW, *pcbAttrLen, (char**) &pbAttrA, 0, NULL, - NULL); + ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) pbAttrW, *pcbAttrLen, (char**) &pbAttrA, 0, NULL, + NULL); namePCSC = pbAttrA; PCSC_SCardFreeMemory_Internal(hContext, pbAttrW); } @@ -2461,24 +2056,8 @@ WINSCARDAPI LONG WINAPI PCSC_SCardGetAttrib_FriendlyName(SCARDHANDLE hCard, DWOR } length = strlen(namePCSC); - nameWinSCard = PCSC_GetReaderAliasFromName(namePCSC); - - if (nameWinSCard) - { - length = strlen(nameWinSCard); - friendlyNameA = _strdup(nameWinSCard); - - if (!friendlyNameA) - { - free(namePCSC); - return SCARD_E_NO_MEMORY; - } - } - else - { - friendlyNameA = namePCSC; - namePCSC = NULL; - } + friendlyNameA = namePCSC; + namePCSC = NULL; if (dwAttrId == SCARD_ATTR_DEVICE_FRIENDLY_NAME_W) { @@ -2540,7 +2119,6 @@ WINSCARDAPI LONG WINAPI PCSC_SCardGetAttrib_FriendlyName(SCARDHANDLE hCard, DWOR } free(namePCSC); - free(nameWinSCard); return status; } @@ -2834,27 +2412,6 @@ WINSCARDAPI LONG WINAPI PCSC_SCardAudit(SCARDCONTEXT hContext, DWORD dwEvent) return 0; } -WINSCARDAPI LONG WINAPI PCSC_SCardAddReaderName(HANDLE* key, LPSTR readerName) -{ - LONG status = SCARD_S_SUCCESS; - int count = 0; - - if (!g_ReadersNames) - { - g_ReadersNames = ListDictionary_New(TRUE); - - if (!g_ReadersNames) - return SCARD_E_NO_SERVICE; - } - - count = ListDictionary_Count(g_ReadersNames); - - if (!ListDictionary_Add(g_ReadersNames, key, readerName)) - return SCARD_E_NO_SERVICE; - - return status; -} - #ifdef __MACOSX__ unsigned int determineMacOSXVersion(void) { @@ -3064,8 +2621,7 @@ SCardApiFunctionTable PCSC_SCardApiFunctionTable = PCSC_SCardGetReaderDeviceInstanceIdW, /* SCardGetReaderDeviceInstanceIdW */ PCSC_SCardListReadersWithDeviceInstanceIdA, /* SCardListReadersWithDeviceInstanceIdA */ PCSC_SCardListReadersWithDeviceInstanceIdW, /* SCardListReadersWithDeviceInstanceIdW */ - PCSC_SCardAudit, /* SCardAudit */ - PCSC_SCardAddReaderName /* SCardAddReaderName */ + PCSC_SCardAudit /* SCardAudit */ }; PSCardApiFunctionTable PCSC_GetSCardApiFunctionTable(void) diff --git a/winpr/libwinpr/smartcard/smartcard_pcsc.h b/winpr/libwinpr/smartcard/smartcard_pcsc.h index 85d1c32fe..1d85d2567 100644 --- a/winpr/libwinpr/smartcard/smartcard_pcsc.h +++ b/winpr/libwinpr/smartcard/smartcard_pcsc.h @@ -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; diff --git a/winpr/libwinpr/smartcard/smartcard_winscard.c b/winpr/libwinpr/smartcard/smartcard_winscard.c index c4b3b6f2c..29f1002aa 100644 --- a/winpr/libwinpr/smartcard/smartcard_winscard.c +++ b/winpr/libwinpr/smartcard/smartcard_winscard.c @@ -111,8 +111,7 @@ SCardApiFunctionTable WinSCard_SCardApiFunctionTable = NULL, /* SCardGetReaderDeviceInstanceIdW */ NULL, /* SCardListReadersWithDeviceInstanceIdA */ NULL, /* SCardListReadersWithDeviceInstanceIdW */ - NULL, /* SCardAudit */ - NULL /* SCardAddReaderName */ + NULL /* SCardAudit */ }; PSCardApiFunctionTable WinSCard_GetSCardApiFunctionTable(void) diff --git a/winpr/libwinpr/smartcard/test/TestSmartCardStatus.c b/winpr/libwinpr/smartcard/test/TestSmartCardStatus.c new file mode 100644 index 000000000..a830685e1 --- /dev/null +++ b/winpr/libwinpr/smartcard/test/TestSmartCardStatus.c @@ -0,0 +1,166 @@ +// compile against PCSC gcc -o scardtest TestSmartCardStatus.c -DPCSC=1 -I /usr/include/PCSC -lpcsclite +#include +#include +#include +#if defined(__APPLE__) || defined(PCSC) +#include +#include +#elif defined (__linux__) +#include +#include +#include +#else +#include +#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; +}