diff --git a/channels/rdpdr/client/irp.c b/channels/rdpdr/client/irp.c index f5ad4861a..b818b67ac 100644 --- a/channels/rdpdr/client/irp.c +++ b/channels/rdpdr/client/irp.c @@ -73,8 +73,7 @@ static UINT irp_complete(IRP* irp) error = rdpdr_send(rdpdr, irp->output); irp->output = NULL; - irp_free(irp); - return error; + return irp_free(irp); } IRP* irp_new(DEVMAN* devman, wStream* s, UINT* error) diff --git a/channels/rdpdr/client/rdpdr_main.c b/channels/rdpdr/client/rdpdr_main.c index affbcfe46..8f7eda847 100644 --- a/channels/rdpdr/client/rdpdr_main.c +++ b/channels/rdpdr/client/rdpdr_main.c @@ -1471,7 +1471,7 @@ static UINT rdpdr_virtual_channel_event_data_received(rdpdrPlugin* rdpdr, void* data_in = rdpdr->data_in; - if (!Stream_EnsureRemainingCapacity(data_in, (int)dataLength)) + if (!Stream_EnsureRemainingCapacity(data_in, dataLength)) { WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); return ERROR_INVALID_DATA; @@ -1602,6 +1602,12 @@ static DWORD WINAPI rdpdr_virtual_channel_client_thread(LPVOID arg) return 0; } +static void queue_free(void* obj) +{ + wStream* s = obj; + Stream_Free(s, TRUE); +} + /** * Function description * @@ -1630,6 +1636,8 @@ static UINT rdpdr_virtual_channel_event_connected(rdpdrPlugin* rdpdr, LPVOID pDa return CHANNEL_RC_NO_MEMORY; } + rdpdr->queue->object.fnObjectFree = queue_free; + if (!(rdpdr->thread = CreateThread(NULL, 0, rdpdr_virtual_channel_client_thread, (void*)rdpdr, 0, NULL))) { diff --git a/channels/smartcard/client/smartcard_operations.c b/channels/smartcard/client/smartcard_operations.c index 15a85568e..13035fd90 100644 --- a/channels/smartcard/client/smartcard_operations.c +++ b/channels/smartcard/client/smartcard_operations.c @@ -211,7 +211,8 @@ static LONG smartcard_EstablishContext_Decode(SMARTCARD_DEVICE* smartcard, if (!call) return STATUS_NO_MEMORY; - if ((status = smartcard_unpack_establish_context_call(smartcard, irp->input, call))) + status = smartcard_unpack_establish_context_call(smartcard, irp->input, call); + if (status != SCARD_S_SUCCESS) { return log_status_error(TAG, "smartcard_unpack_establish_context_call", status); } @@ -223,7 +224,7 @@ static LONG smartcard_EstablishContext_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) { LONG status; - SCARDCONTEXT hContext = -1; + SCARDCONTEXT hContext = { 0 }; EstablishContext_Return ret; IRP* irp = operation->irp; EstablishContext_Call* call = operation->call; @@ -255,7 +256,8 @@ static LONG smartcard_EstablishContext_Call(SMARTCARD_DEVICE* smartcard, smartcard_scard_context_native_to_redir(smartcard, &(ret.hContext), hContext); - if ((status = smartcard_pack_establish_context_return(smartcard, irp->output, &ret))) + status = smartcard_pack_establish_context_return(smartcard, irp->output, &ret); + if (status != SCARD_S_SUCCESS) { return log_status_error(TAG, "smartcard_pack_establish_context_return", status); } @@ -274,7 +276,8 @@ static LONG smartcard_ReleaseContext_Decode(SMARTCARD_DEVICE* smartcard, if (!call) return STATUS_NO_MEMORY; - if ((status = smartcard_unpack_context_call(smartcard, irp->input, call, "ReleaseContext"))) + status = smartcard_unpack_context_call(smartcard, irp->input, call, "ReleaseContext"); + if (status != SCARD_S_SUCCESS) log_status_error(TAG, "smartcard_unpack_context_call", status); operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext)); @@ -364,7 +367,7 @@ static LONG smartcard_ListReaderGroupsA_Call(SMARTCARD_DEVICE* smartcard, if (status != SCARD_S_SUCCESS) return status; - status = smartcard_pack_list_reader_groups_return(smartcard, irp->output, &ret); + status = smartcard_pack_list_reader_groups_return(smartcard, irp->output, &ret, FALSE); if (status != SCARD_S_SUCCESS) return status; @@ -409,7 +412,7 @@ static LONG smartcard_ListReaderGroupsW_Call(SMARTCARD_DEVICE* smartcard, if (status != SCARD_S_SUCCESS) return status; - status = smartcard_pack_list_reader_groups_return(smartcard, irp->output, &ret); + status = smartcard_pack_list_reader_groups_return(smartcard, irp->output, &ret, TRUE); if (status != SCARD_S_SUCCESS) return status; @@ -538,7 +541,7 @@ static LONG smartcard_ListReadersA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_O call->mszGroups = NULL; } - if (status) + if (status != SCARD_S_SUCCESS) { return log_status_error(TAG, "SCardListReadersA", status); } @@ -547,7 +550,8 @@ static LONG smartcard_ListReadersA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_O ret.msz = (BYTE*)mszReaders; ret.cBytes = cchReaders; - if ((status = smartcard_pack_list_readers_return(smartcard, irp->output, &ret, FALSE))) + status = smartcard_pack_list_readers_return(smartcard, irp->output, &ret, FALSE); + if (status != SCARD_S_SUCCESS) { return log_status_error(TAG, "smartcard_pack_list_readers_return", status); } @@ -684,7 +688,6 @@ static LONG smartcard_ListReadersW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_O { LONG status; ListReaders_Return ret; - LPWSTR mszReaders = NULL; DWORD cchReaders = 0; IRP* irp = operation->irp; ListReaders_Call* call = operation->call; @@ -693,11 +696,17 @@ static LONG smartcard_ListReadersW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_O const char* sz; const WCHAR* wz; } string; + union { + WCHAR** ppw; + WCHAR* pw; + CHAR* pc; + BYTE* pb; + } mszReaders; string.bp = call->mszGroups; cchReaders = SCARD_AUTOALLOCATE; status = ret.ReturnCode = - SCardListReadersW(operation->hContext, string.wz, (LPWSTR)&mszReaders, &cchReaders); + SCardListReadersW(operation->hContext, string.wz, (LPWSTR)&mszReaders.pw, &cchReaders); if (call->mszGroups) { @@ -708,14 +717,13 @@ static LONG smartcard_ListReadersW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_O if (status != SCARD_S_SUCCESS) return log_status_error(TAG, "SCardListReadersW", status); - cchReaders = filter_device_by_name_w(smartcard->names, &mszReaders, cchReaders); - ret.msz = (BYTE*)mszReaders; - ret.cBytes = cchReaders * 2; - + cchReaders = filter_device_by_name_w(smartcard->names, &mszReaders.pw, cchReaders); + ret.msz = mszReaders.pb; + ret.cBytes = cchReaders; status = smartcard_pack_list_readers_return(smartcard, irp->output, &ret, TRUE); - if (mszReaders) - SCardFreeMemory(operation->hContext, mszReaders); + if (mszReaders.pb) + SCardFreeMemory(operation->hContext, mszReaders.pb); if (status != SCARD_S_SUCCESS) return status; @@ -945,24 +953,36 @@ static LONG smartcard_ReadCacheA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPE ReadCache_Return ret = { 0 }; ReadCacheA_Call* call = operation->call; IRP* irp = operation->irp; + BOOL autoalloc = (call->Common.cbDataLen == SCARD_AUTOALLOCATE); if (!call->Common.fPbDataIsNULL) { ret.cbDataLen = call->Common.cbDataLen; - ret.pbData = malloc(ret.cbDataLen); - if (!ret.pbData) - return SCARD_F_INTERNAL_ERROR; + if (autoalloc) + { + ret.pbData = malloc(ret.cbDataLen); + if (!ret.pbData) + return SCARD_F_INTERNAL_ERROR; + } } - ret.ReturnCode = SCardReadCacheA(operation->hContext, call->Common.CardIdentifier, - call->Common.FreshnessCounter, call->szLookupName, ret.pbData, - &ret.cbDataLen); + if (autoalloc) + ret.ReturnCode = SCardReadCacheA(operation->hContext, call->Common.CardIdentifier, + call->Common.FreshnessCounter, call->szLookupName, + (BYTE*)&ret.pbData, &ret.cbDataLen); + else + ret.ReturnCode = SCardReadCacheA(operation->hContext, call->Common.CardIdentifier, + call->Common.FreshnessCounter, call->szLookupName, + ret.pbData, &ret.cbDataLen); log_status_error(TAG, "SCardReadCacheA", ret.ReturnCode); free(call->szLookupName); free(call->Common.CardIdentifier); status = smartcard_pack_read_cache_return(smartcard, irp->output, &ret); - free(ret.pbData); + if (autoalloc) + SCardFreeMemory(operation->hContext, ret.pbData); + else + free(ret.pbData); if (status != SCARD_S_SUCCESS) return status; @@ -975,24 +995,35 @@ static LONG smartcard_ReadCacheW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPE ReadCache_Return ret = { 0 }; ReadCacheW_Call* call = operation->call; IRP* irp = operation->irp; - + BOOL autoalloc = (call->Common.cbDataLen == SCARD_AUTOALLOCATE); if (!call->Common.fPbDataIsNULL) { ret.cbDataLen = call->Common.cbDataLen; - ret.pbData = malloc(ret.cbDataLen); - if (!ret.pbData) - return SCARD_F_INTERNAL_ERROR; + if (autoalloc) + { + ret.pbData = malloc(ret.cbDataLen); + if (!ret.pbData) + return SCARD_F_INTERNAL_ERROR; + } } - ret.ReturnCode = SCardReadCacheW(operation->hContext, call->Common.CardIdentifier, - call->Common.FreshnessCounter, call->szLookupName, ret.pbData, - &ret.cbDataLen); + if (autoalloc) + ret.ReturnCode = SCardReadCacheW(operation->hContext, call->Common.CardIdentifier, + call->Common.FreshnessCounter, call->szLookupName, + (BYTE*)&ret.pbData, &ret.cbDataLen); + else + ret.ReturnCode = SCardReadCacheW(operation->hContext, call->Common.CardIdentifier, + call->Common.FreshnessCounter, call->szLookupName, + ret.pbData, &ret.cbDataLen); log_status_error(TAG, "SCardReadCacheW", ret.ReturnCode); free(call->szLookupName); free(call->Common.CardIdentifier); status = smartcard_pack_read_cache_return(smartcard, irp->output, &ret); - free(ret.pbData); + if (autoalloc) + SCardFreeMemory(operation->hContext, ret.pbData); + else + free(ret.pbData); if (status != SCARD_S_SUCCESS) return status; @@ -1042,7 +1073,8 @@ static LONG smartcard_GetTransmitCount_Call(SMARTCARD_DEVICE* smartcard, ret.ReturnCode = SCardGetTransmitCount(operation->hContext, &ret.cTransmitCount); log_status_error(TAG, "SCardGetTransmitCount", ret.ReturnCode); - if ((status = smartcard_pack_get_transmit_count_return(smartcard, irp->output, &ret))) + status = smartcard_pack_get_transmit_count_return(smartcard, irp->output, &ret); + if (status != SCARD_S_SUCCESS) return status; return ret.ReturnCode; @@ -1074,7 +1106,7 @@ static LONG smartcard_GetReaderIcon_Call(SMARTCARD_DEVICE* smartcard, free(call->szReaderName); status = smartcard_pack_get_reader_icon_return(smartcard, irp->output, &ret); SCardFreeMemory(operation->hContext, ret.pbData); - if (status) + if (status != SCARD_S_SUCCESS) return status; return ret.ReturnCode; @@ -1094,7 +1126,7 @@ static LONG smartcard_GetDeviceTypeId_Call(SMARTCARD_DEVICE* smartcard, free(call->szReaderName); status = smartcard_pack_device_type_id_return(smartcard, irp->output, &ret); - if (status) + if (status != SCARD_S_SUCCESS) return status; return ret.ReturnCode; @@ -1144,7 +1176,8 @@ static LONG smartcard_GetStatusChangeA_Call(SMARTCARD_DEVICE* smartcard, ret.rgReaderStates[index].dwCurrentState = call->rgReaderStates[index].dwCurrentState; ret.rgReaderStates[index].dwEventState = call->rgReaderStates[index].dwEventState; ret.rgReaderStates[index].cbAtr = call->rgReaderStates[index].cbAtr; - CopyMemory(&(ret.rgReaderStates[index].rgbAtr), &(call->rgReaderStates[index].rgbAtr), 32); + CopyMemory(&(ret.rgReaderStates[index].rgbAtr), &(call->rgReaderStates[index].rgbAtr), + sizeof(ret.rgReaderStates[index].rgbAtr)); } smartcard_pack_get_status_change_return(smartcard, irp->output, &ret, FALSE); @@ -1208,7 +1241,8 @@ static LONG smartcard_GetStatusChangeW_Call(SMARTCARD_DEVICE* smartcard, ret.rgReaderStates[index].dwCurrentState = call->rgReaderStates[index].dwCurrentState; ret.rgReaderStates[index].dwEventState = call->rgReaderStates[index].dwEventState; ret.rgReaderStates[index].cbAtr = call->rgReaderStates[index].cbAtr; - CopyMemory(&(ret.rgReaderStates[index].rgbAtr), &(call->rgReaderStates[index].rgbAtr), 32); + CopyMemory(&(ret.rgReaderStates[index].rgbAtr), &(call->rgReaderStates[index].rgbAtr), + sizeof(ret.rgReaderStates[index].rgbAtr)); } smartcard_pack_get_status_change_return(smartcard, irp->output, &ret, TRUE); @@ -1290,13 +1324,6 @@ static LONG smartcard_ConnectA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERA call->Common.dwPreferredProtocols, &hCard, &ret.dwActiveProtocol); smartcard_scard_context_native_to_redir(smartcard, &(ret.hContext), operation->hContext); smartcard_scard_handle_native_to_redir(smartcard, &(ret.hCard), hCard); - smartcard_trace_connect_return(smartcard, &ret); - - if (status) - { - log_status_error(TAG, "SCardConnectA", status); - goto out_fail; - } status = smartcard_pack_connect_return(smartcard, irp->output, &ret); if (status != SCARD_S_SUCCESS) @@ -1344,13 +1371,6 @@ static LONG smartcard_ConnectW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERA call->Common.dwPreferredProtocols, &hCard, &ret.dwActiveProtocol); smartcard_scard_context_native_to_redir(smartcard, &(ret.hContext), operation->hContext); smartcard_scard_handle_native_to_redir(smartcard, &(ret.hCard), hCard); - smartcard_trace_connect_return(smartcard, &ret); - - if (status) - { - log_status_error(TAG, "SCardConnectW", status); - goto out_fail; - } status = smartcard_pack_connect_return(smartcard, irp->output, &ret); if (status != SCARD_S_SUCCESS) @@ -1545,7 +1565,7 @@ static LONG smartcard_StatusA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERAT LPSTR mszReaderNames = NULL; IRP* irp = operation->irp; Status_Call* call = operation->call; - ZeroMemory(ret.pbAtr, 32); + call->cbAtrLen = 32; cbAtrLen = call->cbAtrLen; @@ -1601,8 +1621,7 @@ static LONG smartcard_StatusW_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPER static LONG smartcard_StatusW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) { LONG status; - Status_Return ret; - DWORD cchReaderLen = 0; + Status_Return ret = { 0 }; LPWSTR mszReaderNames = NULL; IRP* irp = operation->irp; Status_Call* call = operation->call; @@ -1615,28 +1634,19 @@ static LONG smartcard_StatusW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERAT cbAtrLen = call->cbAtrLen = 32; if (call->fmszReaderNamesIsNULL) - cchReaderLen = 0; + ret.cBytes = 0; else - cchReaderLen = SCARD_AUTOALLOCATE; + ret.cBytes = SCARD_AUTOALLOCATE; - ZeroMemory(ret.pbAtr, 32); status = ret.ReturnCode = SCardStatusW(operation->hCard, call->fmszReaderNamesIsNULL ? NULL : (LPWSTR)&mszReaderNames, - &cchReaderLen, &ret.dwState, &ret.dwProtocol, (BYTE*)&ret.pbAtr, &cbAtrLen); + &ret.cBytes, &ret.dwState, &ret.dwProtocol, (BYTE*)&ret.pbAtr, &cbAtrLen); log_status_error(TAG, "SCardStatusW", status); if (status == SCARD_S_SUCCESS) { if (!call->fmszReaderNamesIsNULL) ret.mszReaderNames = (BYTE*)mszReaderNames; - // WinScard returns the number of CHARACTERS whereas pcsc-lite returns the - // number of BYTES. -#ifdef _WIN32 - ret.cBytes = cchReaderLen * 2; -#else - ret.cBytes = cchReaderLen; -#endif - ret.cbAtrLen = cbAtrLen; } @@ -1701,7 +1711,7 @@ static LONG smartcard_Transmit_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERA free(call->pioSendPci); free(call->pioRecvPci); - if (status) + if (status != SCARD_S_SUCCESS) return status; return ret.ReturnCode; } @@ -1811,23 +1821,14 @@ static LONG smartcard_GetAttrib_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPER autoAllocate ? (LPBYTE) & (ret.pbAttr) : ret.pbAttr, &cbAttrLen); log_status_error(TAG, "SCardGetAttrib", ret.ReturnCode); ret.cbAttrLen = cbAttrLen; - free(ret.pbAttr); - - if (ret.ReturnCode) - { - WLog_WARN(TAG, "SCardGetAttrib: %s (0x%08" PRIX32 ") cbAttrLen: %" PRIu32 "", - SCardGetAttributeString(call->dwAttrId), call->dwAttrId, call->cbAttrLen); - Stream_Zero(irp->output, 256); - - return ret.ReturnCode; - } status = smartcard_pack_get_attrib_return(smartcard, irp->output, &ret, call->dwAttrId); - if (status != SCARD_S_SUCCESS) - return status; - - return ret.ReturnCode; + if (autoAllocate) + SCardFreeMemory(operation->hContext, ret.pbAttr); + else + free(ret.pbAttr); + return status; } static LONG smartcard_SetAttrib_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) @@ -2115,7 +2116,8 @@ static LONG smartcard_LocateCardsByATRA_Call(SMARTCARD_DEVICE* smartcard, ret.rgReaderStates[i].dwCurrentState = state->dwCurrentState; ret.rgReaderStates[i].dwEventState = state->dwEventState; ret.rgReaderStates[i].cbAtr = state->cbAtr; - CopyMemory(&(ret.rgReaderStates[i].rgbAtr), &(state->rgbAtr), 32); + CopyMemory(&(ret.rgReaderStates[i].rgbAtr), &(state->rgbAtr), + sizeof(ret.rgReaderStates[i].rgbAtr)); } free(states); @@ -2184,10 +2186,12 @@ LONG smartcard_irp_device_control_decode(SMARTCARD_DEVICE* smartcard, if ((ioControlCode != SCARD_IOCTL_ACCESSSTARTEDEVENT) && (ioControlCode != SCARD_IOCTL_RELEASETARTEDEVENT)) { - if ((status = smartcard_unpack_common_type_header(smartcard, irp->input))) + status = smartcard_unpack_common_type_header(smartcard, irp->input); + if (status != SCARD_S_SUCCESS) return status; - if ((status = smartcard_unpack_private_type_header(smartcard, irp->input))) + status = smartcard_unpack_private_type_header(smartcard, irp->input); + if (status != SCARD_S_SUCCESS) return status; } @@ -2451,7 +2455,9 @@ LONG smartcard_irp_device_control_call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OP * Since it's a SHOULD and not a MUST, we don't care * about it, but we still reserve at least 2048 bytes. */ - Stream_EnsureRemainingCapacity(irp->output, 2048); + if (!Stream_EnsureRemainingCapacity(irp->output, 2048)) + return SCARD_E_NO_MEMORY; + /* Device Control Response */ Stream_Seek_UINT32(irp->output); /* OutputBufferLength (4 bytes) */ Stream_Seek(irp->output, SMARTCARD_COMMON_TYPE_HEADER_LENGTH); /* CommonTypeHeader (8 bytes) */ @@ -2687,7 +2693,7 @@ LONG smartcard_irp_device_control_call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OP irp->IoStatus = STATUS_SUCCESS; - if ((result & 0xC0000000) == 0xC0000000) + if ((result & 0xC0000000L) == 0xC0000000L) { /* NTSTATUS error */ irp->IoStatus = (UINT32)result; @@ -2704,7 +2710,7 @@ LONG smartcard_irp_device_control_call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OP 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_Write_INT32(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 9079f7971..197345d09 100644 --- a/channels/smartcard/client/smartcard_pack.c +++ b/channels/smartcard/client/smartcard_pack.c @@ -5,6 +5,8 @@ * Copyright 2014 Marc-Andre Moreau * Copyright 2015 Thincast Technologies GmbH * Copyright 2015 DI (FH) Martin Haimberger + * Copyright 2020 Armin Novak + * Copyright 2020 Thincast Technologies GmbH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,14 +30,25 @@ #include "smartcard_pack.h" -static LONG smartcard_unpack_redir_scard_context(SMARTCARD_DEVICE* smartcard, wStream* s, - REDIR_SCARDCONTEXT* context); +static const DWORD g_LogLevel = WLOG_DEBUG; + +#define smartcard_unpack_redir_scard_context(smartcard, s, context, index) \ + smartcard_unpack_redir_scard_context_((smartcard), (s), (context), (index), __FILE__, \ + __FUNCTION__, __LINE__) +#define smartcard_unpack_redir_scard_handle(smartcard, s, context, index) \ + smartcard_unpack_redir_scard_handle_((smartcard), (s), (context), (index), __FILE__, \ + __FUNCTION__, __LINE__) + +static LONG smartcard_unpack_redir_scard_context_(SMARTCARD_DEVICE* smartcard, wStream* s, + REDIR_SCARDCONTEXT* context, UINT32* index, + const char* file, const char* function, int line); static LONG smartcard_pack_redir_scard_context(SMARTCARD_DEVICE* smartcard, wStream* s, - const REDIR_SCARDCONTEXT* context); -static LONG smartcard_unpack_redir_scard_handle(SMARTCARD_DEVICE* smartcard, wStream* s, - REDIR_SCARDHANDLE* handle); + const REDIR_SCARDCONTEXT* context, DWORD* index); +static LONG smartcard_unpack_redir_scard_handle_(SMARTCARD_DEVICE* smartcard, wStream* s, + REDIR_SCARDHANDLE* handle, UINT32* index, + const char* file, const char* function, int line); static LONG smartcard_pack_redir_scard_handle(SMARTCARD_DEVICE* smartcard, wStream* s, - const REDIR_SCARDHANDLE* handle); + const REDIR_SCARDHANDLE* handle, DWORD* index); static LONG smartcard_unpack_redir_scard_context_ref(SMARTCARD_DEVICE* smartcard, wStream* s, REDIR_SCARDCONTEXT* context); static LONG smartcard_pack_redir_scard_context_ref(SMARTCARD_DEVICE* smartcard, wStream* s, @@ -46,18 +59,103 @@ static LONG smartcard_unpack_redir_scard_handle_ref(SMARTCARD_DEVICE* smartcard, static LONG smartcard_pack_redir_scard_handle_ref(SMARTCARD_DEVICE* smartcard, wStream* s, const REDIR_SCARDHANDLE* handle); -static LONG smartcard_ndr_read(wStream* s, BYTE** data, size_t min) +typedef enum { - UINT32 len; - void* r; + NDR_PTR_FULL, + NDR_PTR_SIMPLE, + NDR_PTR_FIXED +} ndr_ptr_t; +/* Reads a NDR pointer and checks if the value read has the expected relative + * addressing */ +#define smartcard_ndr_pointer_read(s, index, ptr) \ + smartcard_ndr_pointer_read_((s), (index), (ptr), __FILE__, __FUNCTION__, __LINE__) +static BOOL smartcard_ndr_pointer_read_(wStream* s, UINT32* index, UINT32* ptr, const char* file, + const char* fkt, int line) +{ + const UINT32 expect = 0x20000 + (*index) * 4; + UINT32 ndrPtr; + WINPR_UNUSED(file); + if (!s) + return FALSE; if (Stream_GetRemainingLength(s) < 4) + return FALSE; + + Stream_Read_UINT32(s, ndrPtr); /* mszGroupsNdrPtr (4 bytes) */ + if (ptr) + *ptr = ndrPtr; + if (expect != ndrPtr) + { + /* Allow NULL pointer if we read the result */ + if (ptr && (ndrPtr == 0)) + return TRUE; + WLog_WARN(TAG, "[%s:%d] Read context pointer 0x%08" PRIx32 ", expected 0x%08" PRIx32, fkt, + line, ndrPtr, expect); + return FALSE; + } + + (*index) = (*index) + 1; + return TRUE; +} + +static LONG smartcard_ndr_read(wStream* s, BYTE** data, size_t min, size_t elementSize, + ndr_ptr_t type) +{ + UINT32 len, offset, len2; + void* r; + size_t required; + + switch (type) + { + case NDR_PTR_FULL: + required = 12; + break; + case NDR_PTR_SIMPLE: + required = 4; + break; + case NDR_PTR_FIXED: + required = min; + break; + } + + if (Stream_GetRemainingLength(s) < required) { WLog_ERR(TAG, "Short data while trying to read NDR pointer, expected 4, got %" PRIu32, Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } - Stream_Read_UINT32(s, len); + + switch (type) + { + case NDR_PTR_FULL: + Stream_Read_UINT32(s, len); + Stream_Read_UINT32(s, offset); + Stream_Read_UINT32(s, len2); + if (len != offset + len2) + { + WLog_ERR(TAG, + "Invalid data when reading full NDR pointer: total=%" PRIu32 + ", offset=%" PRIu32 ", remaining=%" PRIu32, + len, offset, len2); + return STATUS_BUFFER_TOO_SMALL; + } + break; + case NDR_PTR_SIMPLE: + Stream_Read_UINT32(s, len); + + if ((len != min) && (min > 0)) + { + WLog_ERR(TAG, + "Invalid data when reading simple NDR pointer: total=%" PRIu32 + ", expected=%" PRIu32, + len, min); + return STATUS_BUFFER_TOO_SMALL; + } + break; + case NDR_PTR_FIXED: + len = (UINT32)min; + break; + } if (min > len) { @@ -65,6 +163,7 @@ static LONG smartcard_ndr_read(wStream* s, BYTE** data, size_t min) min, len); return STATUS_DATA_ERROR; } + len *= elementSize; if (Stream_GetRemainingLength(s) < len) { @@ -79,38 +178,149 @@ static LONG smartcard_ndr_read(wStream* s, BYTE** data, size_t min) if (!r) return SCARD_E_NO_MEMORY; Stream_Read(s, r, len); + smartcard_unpack_read_size_align(NULL, s, len, 4); *data = r; return STATUS_SUCCESS; } -static LONG smartcard_ndr_read_a(wStream* s, CHAR** data, size_t min) +static BOOL smartcard_ndr_pointer_write(wStream* s, UINT32* index, DWORD length) +{ + const UINT32 ndrPtr = 0x20000 + (*index) * 4; + + if (!s) + return FALSE; + if (!Stream_EnsureRemainingCapacity(s, 4)) + return FALSE; + + if (length > 0) + { + Stream_Write_UINT32(s, ndrPtr); /* mszGroupsNdrPtr (4 bytes) */ + (*index) = (*index) + 1; + } + else + Stream_Write_UINT32(s, 0); + return TRUE; +} + +static LONG smartcard_ndr_write(wStream* s, const BYTE* data, UINT32 size, UINT32 elementSize, + ndr_ptr_t type) +{ + const UINT32 offset = 0; + const UINT32 len = size; + const UINT32 dataLen = size * elementSize; + size_t required; + + if (size == 0) + return SCARD_S_SUCCESS; + + switch (type) + { + case NDR_PTR_FULL: + required = 12; + break; + case NDR_PTR_SIMPLE: + required = 4; + break; + case NDR_PTR_FIXED: + required = 0; + break; + } + + if (!Stream_EnsureRemainingCapacity(s, required + dataLen + 4)) + return STATUS_BUFFER_TOO_SMALL; + + switch (type) + { + case NDR_PTR_FULL: + Stream_Write_UINT32(s, len); + Stream_Write_UINT32(s, offset); + Stream_Write_UINT32(s, len); + break; + case NDR_PTR_SIMPLE: + Stream_Write_UINT32(s, len); + break; + case NDR_PTR_FIXED: + break; + } + + if (data) + Stream_Write(s, data, dataLen); + else + Stream_Zero(s, dataLen); + return smartcard_pack_write_size_align(NULL, s, len, 4); +} + +static LONG smartcard_ndr_write_state(wStream* s, const ReaderState_Return* data, UINT32 size, + ndr_ptr_t type) +{ + union { + const ReaderState_Return* reader; + const BYTE* data; + } cnv; + + cnv.reader = data; + return smartcard_ndr_write(s, cnv.data, size, sizeof(ReaderState_Return), type); +} + +static LONG smartcard_ndr_read_atrmask(wStream* s, LocateCards_ATRMask** data, size_t min, + ndr_ptr_t type) +{ + union { + LocateCards_ATRMask** ppc; + BYTE** ppv; + } u; + u.ppc = data; + return smartcard_ndr_read(s, u.ppv, min, sizeof(LocateCards_ATRMask), type); +} + +static LONG smartcard_ndr_read_fixed_string_a(wStream* s, CHAR** data, size_t min, ndr_ptr_t type) { union { CHAR** ppc; BYTE** ppv; } u; u.ppc = data; - return smartcard_ndr_read(s, u.ppv, min); + return smartcard_ndr_read(s, u.ppv, min, sizeof(CHAR), type); } -static LONG smartcard_ndr_read_w(wStream* s, WCHAR** data, size_t min) +static LONG smartcard_ndr_read_fixed_string_w(wStream* s, WCHAR** data, size_t min, ndr_ptr_t type) { union { WCHAR** ppc; BYTE** ppv; } u; u.ppc = data; - return smartcard_ndr_read(s, u.ppv, min); + return smartcard_ndr_read(s, u.ppv, min, sizeof(WCHAR), type); } -static LONG smartcard_ndr_read_u(wStream* s, UUID** data, size_t min) +static LONG smartcard_ndr_read_a(wStream* s, CHAR** data, ndr_ptr_t type) +{ + union { + CHAR** ppc; + BYTE** ppv; + } u; + u.ppc = data; + return smartcard_ndr_read(s, u.ppv, 0, sizeof(CHAR), type); +} + +static LONG smartcard_ndr_read_w(wStream* s, WCHAR** data, ndr_ptr_t type) +{ + union { + WCHAR** ppc; + BYTE** ppv; + } u; + u.ppc = data; + return smartcard_ndr_read(s, u.ppv, 0, sizeof(WCHAR), type); +} + +static LONG smartcard_ndr_read_u(wStream* s, UUID** data) { union { UUID** ppc; BYTE** ppv; } u; u.ppc = data; - return smartcard_ndr_read(s, u.ppv, min); + return smartcard_ndr_read(s, u.ppv, 1, sizeof(UUID), NDR_PTR_FIXED); } static char* smartcard_convert_string_list(const void* in, size_t bytes, BOOL unicode) @@ -188,28 +398,42 @@ static char* smartcard_array_dump(const void* pd, size_t len, char* buffer, size int rc; char* start = buffer; + /* Ensure '\0' termination */ + if (bufferLen > 0) + { + buffer[bufferLen - 1] = '\0'; + bufferLen--; + } + rc = _snprintf(buffer, bufferLen, "{ "); + if ((rc < 0) || ((size_t)rc > bufferLen)) + goto fail; buffer += rc; bufferLen -= (size_t)rc; for (x = 0; x < len; x++) { rc = _snprintf(buffer, bufferLen, "%02X", data[x]); + if ((rc < 0) || ((size_t)rc > bufferLen)) + goto fail; buffer += rc; bufferLen -= (size_t)rc; } - rc = _snprintf(buffer, bufferLen, "}"); + rc = _snprintf(buffer, bufferLen, " }"); + if ((rc < 0) || ((size_t)rc > bufferLen)) + goto fail; buffer += rc; bufferLen -= (size_t)rc; +fail: return start; } static void smartcard_log_redir_handle(const char* tag, const REDIR_SCARDHANDLE* pHandle) { char buffer[128]; - WLog_DBG(tag, "hContext: %s", + WLog_LVL(tag, g_LogLevel, " hContext: %s", smartcard_array_dump(pHandle->pbHandle, pHandle->cbHandle, buffer, sizeof(buffer))); } @@ -225,14 +449,14 @@ static void smartcard_trace_context_and_string_call_a(const char* name, const REDIR_SCARDCONTEXT* phContext, const CHAR* sz) { - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; - WLog_DBG(TAG, "%s {", name); + WLog_LVL(TAG, g_LogLevel, "%s {", name); smartcard_log_context(TAG, phContext); - WLog_DBG(TAG, " sz=%s", sz); + WLog_LVL(TAG, g_LogLevel, " sz=%s", sz); - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, "}"); } static void smartcard_trace_context_and_string_call_w(const char* name, @@ -240,16 +464,16 @@ static void smartcard_trace_context_and_string_call_w(const char* name, const WCHAR* sz) { char* tmp; - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; - WLog_DBG(TAG, "%s {", name); + WLog_LVL(TAG, g_LogLevel, "%s {", name); smartcard_log_context(TAG, phContext); ConvertFromUnicode(CP_UTF8, 0, sz, -1, &tmp, 0, NULL, NULL); - WLog_DBG(TAG, " sz=%s", tmp); + WLog_LVL(TAG, g_LogLevel, " sz=%s", tmp); free(tmp); - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, "}"); } static void smartcard_trace_context_call(SMARTCARD_DEVICE* smartcard, const Context_Call* call, @@ -257,13 +481,13 @@ static void smartcard_trace_context_call(SMARTCARD_DEVICE* smartcard, const Cont { WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; - WLog_DBG(TAG, "%s_Call {", name); + WLog_LVL(TAG, g_LogLevel, "%s_Call {", name); smartcard_log_context(TAG, &call->hContext); - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, "}"); } static void smartcard_trace_list_reader_groups_call(SMARTCARD_DEVICE* smartcard, @@ -271,15 +495,15 @@ static void smartcard_trace_list_reader_groups_call(SMARTCARD_DEVICE* smartcard, { WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; - WLog_DBG(TAG, "ListReaderGroups%S_Call {", unicode ? "W" : "A"); + WLog_LVL(TAG, g_LogLevel, "ListReaderGroups%S_Call {", unicode ? "W" : "A"); smartcard_log_context(TAG, &call->hContext); - WLog_DBG(TAG, "fmszGroupsIsNULL: %" PRId32 " cchGroups: 0x%08" PRIx32, call->fmszGroupsIsNULL, - call->cchGroups); - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, "fmszGroupsIsNULL: %" PRId32 " cchGroups: 0x%08" PRIx32, + call->fmszGroupsIsNULL, call->cchGroups); + WLog_LVL(TAG, g_LogLevel, "}"); } static void smartcard_trace_get_status_change_w_call(SMARTCARD_DEVICE* smartcard, @@ -291,13 +515,13 @@ static void smartcard_trace_get_status_change_w_call(SMARTCARD_DEVICE* smartcard LPSCARD_READERSTATEW readerState; WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; - WLog_DBG(TAG, "GetStatusChangeW_Call {"); + WLog_LVL(TAG, g_LogLevel, "GetStatusChangeW_Call {"); smartcard_log_context(TAG, &call->hContext); - WLog_DBG(TAG, "dwTimeOut: 0x%08" PRIX32 " cReaders: %" PRIu32 "", call->dwTimeOut, + WLog_LVL(TAG, g_LogLevel, "dwTimeOut: 0x%08" PRIX32 " cReaders: %" PRIu32 "", call->dwTimeOut, call->cReaders); for (index = 0; index < call->cReaders; index++) @@ -305,20 +529,20 @@ static void smartcard_trace_get_status_change_w_call(SMARTCARD_DEVICE* smartcard char* szReaderA = NULL; readerState = &call->rgReaderStates[index]; ConvertFromUnicode(CP_UTF8, 0, readerState->szReader, -1, &szReaderA, 0, NULL, NULL); - WLog_DBG(TAG, "\t[%" PRIu32 "]: szReader: %s cbAtr: %" PRIu32 "", index, szReaderA, - readerState->cbAtr); + WLog_LVL(TAG, g_LogLevel, "\t[%" PRIu32 "]: szReader: %s cbAtr: %" PRIu32 "", index, + szReaderA, readerState->cbAtr); szCurrentState = SCardGetReaderStateString(readerState->dwCurrentState); szEventState = SCardGetReaderStateString(readerState->dwEventState); - WLog_DBG(TAG, "\t[%" PRIu32 "]: dwCurrentState: %s (0x%08" PRIX32 ")", index, + WLog_LVL(TAG, g_LogLevel, "\t[%" PRIu32 "]: dwCurrentState: %s (0x%08" PRIX32 ")", index, szCurrentState, readerState->dwCurrentState); - WLog_DBG(TAG, "\t[%" PRIu32 "]: dwEventState: %s (0x%08" PRIX32 ")", index, szEventState, - readerState->dwEventState); + WLog_LVL(TAG, g_LogLevel, "\t[%" PRIu32 "]: dwEventState: %s (0x%08" PRIX32 ")", index, + szEventState, readerState->dwEventState); free(szCurrentState); free(szEventState); free(szReaderA); } - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, "}"); } static void smartcard_trace_list_reader_groups_return(SMARTCARD_DEVICE* smartcard, @@ -328,16 +552,16 @@ static void smartcard_trace_list_reader_groups_return(SMARTCARD_DEVICE* smartcar char* mszA = NULL; WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; mszA = smartcard_convert_string_list(ret->msz, ret->cBytes, unicode); - WLog_DBG(TAG, "ListReaderGroups%s_Return {", unicode ? "W" : "A"); - WLog_DBG(TAG, "ReturnCode: %s (0x%08" PRIx32 ")", SCardGetErrorString(ret->ReturnCode), - ret->ReturnCode); - WLog_DBG(TAG, "cBytes: %" PRIu32 " msz: %s", ret->cBytes, mszA); - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, "ListReaderGroups%s_Return {", unicode ? "W" : "A"); + WLog_LVL(TAG, g_LogLevel, " ReturnCode: %s (0x%08" PRIx32 ")", + SCardGetErrorString(ret->ReturnCode), ret->ReturnCode); + WLog_LVL(TAG, g_LogLevel, " cBytes: %" PRIu32 " msz: %s", ret->cBytes, mszA); + WLog_LVL(TAG, g_LogLevel, "}"); free(mszA); } @@ -347,19 +571,19 @@ static void smartcard_trace_list_readers_call(SMARTCARD_DEVICE* smartcard, char* mszGroupsA = NULL; WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; mszGroupsA = smartcard_convert_string_list(call->mszGroups, call->cBytes, unicode); - WLog_DBG(TAG, "ListReaders%s_Call {", unicode ? "W" : "A"); + WLog_LVL(TAG, g_LogLevel, "ListReaders%s_Call {", unicode ? "W" : "A"); smartcard_log_context(TAG, &call->hContext); - WLog_DBG(TAG, + WLog_LVL(TAG, g_LogLevel, "cBytes: %" PRIu32 " mszGroups: %s fmszReadersIsNULL: %" PRId32 " cchReaders: 0x%08" PRIX32 "", call->cBytes, mszGroupsA, call->fmszReadersIsNULL, call->cchReaders); - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, "}"); free(mszGroupsA); } @@ -370,45 +594,38 @@ static void smartcard_trace_locate_cards_by_atr_a_call(SMARTCARD_DEVICE* smartca UINT32 index; char* szEventState; char* szCurrentState; - char* rgbAtr; - LPSCARD_READERSTATEA readerState; + WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; - WLog_DBG(TAG, "LocateCardsByATRA_Call {"); + WLog_LVL(TAG, g_LogLevel, "LocateCardsByATRA_Call {"); smartcard_log_context(TAG, &call->hContext); for (index = 0; index < call->cReaders; index++) { - readerState = (LPSCARD_READERSTATEA)&call->rgReaderStates[index]; - WLog_DBG(TAG, "\t[%" PRIu32 "]: szReader: %s cbAtr: %" PRIu32 "", index, + char buffer[1024]; + const LPSCARD_READERSTATEA readerState = &call->rgReaderStates[index]; + + WLog_LVL(TAG, g_LogLevel, "\t[%" PRIu32 "]: szReader: %s cbAtr: %" PRIu32 "", index, readerState->szReader, readerState->cbAtr); szCurrentState = SCardGetReaderStateString(readerState->dwCurrentState); szEventState = SCardGetReaderStateString(readerState->dwEventState); - rgbAtr = winpr_BinToHexString((BYTE*)&(readerState->rgbAtr), readerState->cbAtr, FALSE); - WLog_DBG(TAG, "\t[%" PRIu32 "]: dwCurrentState: %s (0x%08" PRIX32 ")", index, + WLog_LVL(TAG, g_LogLevel, "\t[%" PRIu32 "]: dwCurrentState: %s (0x%08" PRIX32 ")", index, szCurrentState, readerState->dwCurrentState); - WLog_DBG(TAG, "\t[%" PRIu32 "]: dwEventState: %s (0x%08" PRIX32 ")", index, szEventState, - readerState->dwEventState); + WLog_LVL(TAG, g_LogLevel, "\t[%" PRIu32 "]: dwEventState: %s (0x%08" PRIX32 ")", index, + szEventState, readerState->dwEventState); - if (rgbAtr) - { - WLog_DBG(TAG, "\t[%" PRIu32 "]: cbAtr: %" PRIu32 " rgbAtr: %s", index, - readerState->cbAtr, rgbAtr); - } - else - { - WLog_DBG(TAG, "\t[%" PRIu32 "]: cbAtr: 0 rgbAtr: n/a", index); - } + WLog_DBG( + TAG, "\t[%" PRIu32 "]: cbAtr: %" PRIu32 " rgbAtr: %s", index, readerState->cbAtr, + smartcard_array_dump(readerState->rgbAtr, readerState->cbAtr, buffer, sizeof(buffer))); free(szCurrentState); free(szEventState); - free(rgbAtr); } - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, "}"); } static void smartcard_trace_locate_cards_a_call(SMARTCARD_DEVICE* smartcard, @@ -417,90 +634,87 @@ static void smartcard_trace_locate_cards_a_call(SMARTCARD_DEVICE* smartcard, char buffer[8192]; WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; - WLog_DBG(TAG, "LocateCardsA_Call {"); + WLog_LVL(TAG, g_LogLevel, "LocateCardsA_Call {"); smartcard_log_context(TAG, &call->hContext); - WLog_DBG(TAG, " cBytes=%" PRId32, call->cBytes); - WLog_DBG(TAG, " mszCards=%s", + WLog_LVL(TAG, g_LogLevel, " cBytes=%" PRId32, call->cBytes); + WLog_LVL(TAG, g_LogLevel, " mszCards=%s", smartcard_msz_dump_a(call->mszCards, call->cBytes, buffer, sizeof(buffer))); - WLog_DBG(TAG, " cReaders=%" PRId32, call->cReaders); - // WLog_DBG(TAG, " cReaders=%" PRId32, call->rgReaderStates); + WLog_LVL(TAG, g_LogLevel, " cReaders=%" PRId32, call->cReaders); + // WLog_LVL(TAG, g_LogLevel, " cReaders=%" PRId32, call->rgReaderStates); - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, "}"); } static void smartcard_trace_locate_cards_return(SMARTCARD_DEVICE* smartcard, const LocateCards_Return* ret) { WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; - WLog_DBG(TAG, "LocateCards_Return {"); - WLog_DBG(TAG, "ReturnCode: %s (0x%08" PRIX32 ")", SCardGetErrorString(ret->ReturnCode), - ret->ReturnCode); + WLog_LVL(TAG, g_LogLevel, "LocateCards_Return {"); + WLog_LVL(TAG, g_LogLevel, " ReturnCode: %s (0x%08" PRIX32 ")", + SCardGetErrorString(ret->ReturnCode), ret->ReturnCode); if (ret->ReturnCode == SCARD_S_SUCCESS) { - WLog_DBG(TAG, " cReaders=%" PRId32, ret->cReaders); - // WLog_DBG(TAG, " cReaders=%" PRId32, call->rgReaderStates); + WLog_LVL(TAG, g_LogLevel, " cReaders=%" PRId32, ret->cReaders); } - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, "}"); } static void smartcard_trace_get_reader_icon_return(SMARTCARD_DEVICE* smartcard, const GetReaderIcon_Return* ret) { WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; - WLog_DBG(TAG, "GetReaderIcon_Return {"); - WLog_DBG(TAG, "ReturnCode: %s (0x%08" PRIX32 ")", SCardGetErrorString(ret->ReturnCode), - ret->ReturnCode); + WLog_LVL(TAG, g_LogLevel, "GetReaderIcon_Return {"); + WLog_LVL(TAG, g_LogLevel, " ReturnCode: %s (0x%08" PRIX32 ")", + SCardGetErrorString(ret->ReturnCode), ret->ReturnCode); if (ret->ReturnCode == SCARD_S_SUCCESS) { - WLog_DBG(TAG, " cbDataLen=%" PRId32, ret->cbDataLen); - // WLog_DBG(TAG, " cReaders=%" PRId32, call->pbData); + WLog_LVL(TAG, g_LogLevel, " cbDataLen=%" PRId32, ret->cbDataLen); } - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, "}"); } static void smartcard_trace_get_transmit_count_return(SMARTCARD_DEVICE* smartcard, const GetTransmitCount_Return* ret) { WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; - WLog_DBG(TAG, "GetTransmitCount_Return {"); - WLog_DBG(TAG, "ReturnCode: %s (0x%08" PRIX32 ")", SCardGetErrorString(ret->ReturnCode), - ret->ReturnCode); + WLog_LVL(TAG, g_LogLevel, "GetTransmitCount_Return {"); + WLog_LVL(TAG, g_LogLevel, " ReturnCode: %s (0x%08" PRIX32 ")", + SCardGetErrorString(ret->ReturnCode), ret->ReturnCode); - WLog_DBG(TAG, " cTransmitCount=%" PRIu32, ret->cTransmitCount); - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, " cTransmitCount=%" PRIu32, ret->cTransmitCount); + WLog_LVL(TAG, g_LogLevel, "}"); } static void smartcard_trace_read_cache_return(SMARTCARD_DEVICE* smartcard, const ReadCache_Return* ret) { WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; - WLog_DBG(TAG, "ReadCache_Return {"); - WLog_DBG(TAG, "ReturnCode: %s (0x%08" PRIX32 ")", SCardGetErrorString(ret->ReturnCode), - ret->ReturnCode); + WLog_LVL(TAG, g_LogLevel, "ReadCache_Return {"); + WLog_LVL(TAG, g_LogLevel, " ReturnCode: %s (0x%08" PRIX32 ")", + SCardGetErrorString(ret->ReturnCode), ret->ReturnCode); if (ret->ReturnCode == SCARD_S_SUCCESS) { - WLog_DBG(TAG, " cbDataLen=%" PRId32, ret->cbDataLen); - // WLog_DBG(TAG, " cReaders=%" PRId32, call->cReaders); + WLog_LVL(TAG, g_LogLevel, " cbDataLen=%" PRId32, ret->cbDataLen); } - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, "}"); } static void smartcard_trace_locate_cards_w_call(SMARTCARD_DEVICE* smartcard, @@ -508,17 +722,17 @@ static void smartcard_trace_locate_cards_w_call(SMARTCARD_DEVICE* smartcard, { char buffer[8192]; WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; - WLog_DBG(TAG, "LocateCardsW_Call {"); + WLog_LVL(TAG, g_LogLevel, "LocateCardsW_Call {"); smartcard_log_context(TAG, &call->hContext); - WLog_DBG(TAG, " cBytes=%" PRId32, call->cBytes); - WLog_DBG(TAG, " sz2=%s", + WLog_LVL(TAG, g_LogLevel, " cBytes=%" PRId32, call->cBytes); + WLog_LVL(TAG, g_LogLevel, " sz2=%s", smartcard_msz_dump_w(call->mszCards, call->cBytes, buffer, sizeof(buffer))); - WLog_DBG(TAG, " cReaders=%" PRId32, call->cReaders); - // WLog_DBG(TAG, " sz2=%s", call->rgReaderStates); - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, " cReaders=%" PRId32, call->cReaders); + // WLog_LVL(TAG, g_LogLevel, " sz2=%s", call->rgReaderStates); + WLog_LVL(TAG, g_LogLevel, "}"); } static void smartcard_trace_list_readers_return(SMARTCARD_DEVICE* smartcard, @@ -527,23 +741,23 @@ static void smartcard_trace_list_readers_return(SMARTCARD_DEVICE* smartcard, char* mszA = NULL; WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; - WLog_DBG(TAG, "ListReaders%s_Return {", unicode ? "W" : "A"); - WLog_DBG(TAG, "ReturnCode: %s (0x%08" PRIX32 ")", SCardGetErrorString(ret->ReturnCode), - ret->ReturnCode); + WLog_LVL(TAG, g_LogLevel, "ListReaders%s_Return {", unicode ? "W" : "A"); + WLog_LVL(TAG, g_LogLevel, " ReturnCode: %s (0x%08" PRIX32 ")", + SCardGetErrorString(ret->ReturnCode), ret->ReturnCode); if (ret->ReturnCode != SCARD_S_SUCCESS) { - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, "}"); return; } mszA = smartcard_convert_string_list(ret->msz, ret->cBytes, unicode); - WLog_DBG(TAG, "cBytes: %" PRIu32 " msz: %s", ret->cBytes, mszA); - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, " cBytes: %" PRIu32 " msz: %s", ret->cBytes, mszA); + WLog_LVL(TAG, g_LogLevel, "}"); free(mszA); } @@ -552,52 +766,52 @@ static void smartcard_trace_get_status_change_return(SMARTCARD_DEVICE* smartcard BOOL unicode) { UINT32 index; - char* rgbAtr; char* szEventState; char* szCurrentState; - ReaderState_Return* rgReaderState; + WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; - WLog_DBG(TAG, "GetStatusChange%s_Return {", unicode ? "W" : "A"); - WLog_DBG(TAG, "ReturnCode: %s (0x%08" PRIX32 ")", SCardGetErrorString(ret->ReturnCode), - ret->ReturnCode); - WLog_DBG(TAG, "cReaders: %" PRIu32 "", ret->cReaders); + WLog_LVL(TAG, g_LogLevel, "GetStatusChange%s_Return {", unicode ? "W" : "A"); + WLog_LVL(TAG, g_LogLevel, " ReturnCode: %s (0x%08" PRIX32 ")", + SCardGetErrorString(ret->ReturnCode), ret->ReturnCode); + WLog_LVL(TAG, g_LogLevel, " cReaders: %" PRIu32 "", ret->cReaders); for (index = 0; index < ret->cReaders; index++) { - rgReaderState = &(ret->rgReaderStates[index]); + char buffer[1024]; + const ReaderState_Return* rgReaderState = &(ret->rgReaderStates[index]); szCurrentState = SCardGetReaderStateString(rgReaderState->dwCurrentState); szEventState = SCardGetReaderStateString(rgReaderState->dwEventState); - rgbAtr = winpr_BinToHexString((BYTE*)&(rgReaderState->rgbAtr), rgReaderState->cbAtr, FALSE); - WLog_DBG(TAG, "\t[%" PRIu32 "]: dwCurrentState: %s (0x%08" PRIX32 ")", index, + WLog_LVL(TAG, g_LogLevel, " [%" PRIu32 "]: dwCurrentState: %s (0x%08" PRIX32 ")", index, szCurrentState, rgReaderState->dwCurrentState); - WLog_DBG(TAG, "\t[%" PRIu32 "]: dwEventState: %s (0x%08" PRIX32 ")", index, szEventState, - rgReaderState->dwEventState); - WLog_DBG(TAG, "\t[%" PRIu32 "]: cbAtr: %" PRIu32 " rgbAtr: %s", index, rgReaderState->cbAtr, - rgbAtr); + WLog_LVL(TAG, g_LogLevel, " [%" PRIu32 "]: dwEventState: %s (0x%08" PRIX32 ")", index, + szEventState, rgReaderState->dwEventState); + WLog_LVL(TAG, g_LogLevel, " [%" PRIu32 "]: cbAtr: %" PRIu32 " rgbAtr: %s", index, + rgReaderState->cbAtr, + smartcard_array_dump(rgReaderState->rgbAtr, rgReaderState->cbAtr, buffer, + sizeof(buffer))); free(szCurrentState); free(szEventState); - free(rgbAtr); } - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, "}"); } static void smartcard_trace_context_and_two_strings_a_call(SMARTCARD_DEVICE* smartcard, const ContextAndTwoStringA_Call* call) { WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; - WLog_DBG(TAG, "ContextAndTwoStringW_Call {"); + WLog_LVL(TAG, g_LogLevel, "ContextAndTwoStringW_Call {"); smartcard_log_context(TAG, &call->hContext); - WLog_DBG(TAG, " sz1=%s", call->sz1); - WLog_DBG(TAG, " sz2=%s", call->sz2); - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, " sz1=%s", call->sz1); + WLog_LVL(TAG, g_LogLevel, " sz2=%s", call->sz2); + WLog_LVL(TAG, g_LogLevel, "}"); } static void smartcard_trace_context_and_two_strings_w_call(SMARTCARD_DEVICE* smartcard, @@ -607,33 +821,33 @@ static void smartcard_trace_context_and_two_strings_w_call(SMARTCARD_DEVICE* sma CHAR* sz2 = NULL; WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; - WLog_DBG(TAG, "ContextAndTwoStringW_Call {"); + WLog_LVL(TAG, g_LogLevel, "ContextAndTwoStringW_Call {"); smartcard_log_context(TAG, &call->hContext); ConvertFromUnicode(CP_UTF8, 0, call->sz1, -1, &sz1, 0, NULL, NULL); ConvertFromUnicode(CP_UTF8, 0, call->sz2, -1, &sz2, 0, NULL, NULL); - WLog_DBG(TAG, " sz1=%s", sz1); - WLog_DBG(TAG, " sz2=%s", sz2); + WLog_LVL(TAG, g_LogLevel, " sz1=%s", sz1); + WLog_LVL(TAG, g_LogLevel, " sz2=%s", sz2); free(sz1); free(sz2); - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, "}"); } static void smartcard_trace_get_transmit_count_call(SMARTCARD_DEVICE* smartcard, const GetTransmitCount_Call* call) { WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; - WLog_DBG(TAG, "GetTransmitCount_Call {"); + WLog_LVL(TAG, g_LogLevel, "GetTransmitCount_Call {"); smartcard_log_context(TAG, &call->hContext); smartcard_log_redir_handle(TAG, &call->hCard); - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, "}"); } static void smartcard_trace_write_cache_a_call(SMARTCARD_DEVICE* smartcard, @@ -641,23 +855,23 @@ static void smartcard_trace_write_cache_a_call(SMARTCARD_DEVICE* smartcard, { char buffer[1024]; WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; - WLog_DBG(TAG, "GetTransmitCount_Call {"); + WLog_LVL(TAG, g_LogLevel, "GetTransmitCount_Call {"); - WLog_DBG(TAG, " szLookupName=%s", call->szLookupName); + WLog_LVL(TAG, g_LogLevel, " szLookupName=%s", call->szLookupName); smartcard_log_context(TAG, &call->Common.hContext); WLog_DBG( TAG, "..CardIdentifier=%s", smartcard_array_dump(call->Common.CardIdentifier, sizeof(UUID), buffer, sizeof(buffer))); - WLog_DBG(TAG, " FreshnessCounter=%" PRIu32, call->Common.FreshnessCounter); - WLog_DBG(TAG, " cbDataLen=%" PRIu32, call->Common.cbDataLen); + WLog_LVL(TAG, g_LogLevel, " FreshnessCounter=%" PRIu32, call->Common.FreshnessCounter); + WLog_LVL(TAG, g_LogLevel, " cbDataLen=%" PRIu32, call->Common.cbDataLen); WLog_DBG( TAG, " pbData=%s", smartcard_array_dump(call->Common.pbData, call->Common.cbDataLen, buffer, sizeof(buffer))); - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, "}"); } static void smartcard_trace_write_cache_w_call(SMARTCARD_DEVICE* smartcard, @@ -666,24 +880,24 @@ static void smartcard_trace_write_cache_w_call(SMARTCARD_DEVICE* smartcard, char* tmp; char buffer[1024]; WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; - WLog_DBG(TAG, "GetTransmitCount_Call {"); + WLog_LVL(TAG, g_LogLevel, "GetTransmitCount_Call {"); ConvertFromUnicode(CP_UTF8, 0, call->szLookupName, -1, &tmp, 0, NULL, NULL); - WLog_DBG(TAG, " szLookupName=%s", tmp); + WLog_LVL(TAG, g_LogLevel, " szLookupName=%s", tmp); free(tmp); smartcard_log_context(TAG, &call->Common.hContext); WLog_DBG( TAG, "..CardIdentifier=%s", smartcard_array_dump(call->Common.CardIdentifier, sizeof(UUID), buffer, sizeof(buffer))); - WLog_DBG(TAG, " FreshnessCounter=%" PRIu32, call->Common.FreshnessCounter); - WLog_DBG(TAG, " cbDataLen=%" PRIu32, call->Common.cbDataLen); + WLog_LVL(TAG, g_LogLevel, " FreshnessCounter=%" PRIu32, call->Common.FreshnessCounter); + WLog_LVL(TAG, g_LogLevel, " cbDataLen=%" PRIu32, call->Common.cbDataLen); WLog_DBG( TAG, " pbData=%s", smartcard_array_dump(call->Common.pbData, call->Common.cbDataLen, buffer, sizeof(buffer))); - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, "}"); } static void smartcard_trace_read_cache_a_call(SMARTCARD_DEVICE* smartcard, @@ -691,21 +905,21 @@ static void smartcard_trace_read_cache_a_call(SMARTCARD_DEVICE* smartcard, { char buffer[1024]; WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; - WLog_DBG(TAG, "GetTransmitCount_Call {"); + WLog_LVL(TAG, g_LogLevel, "GetTransmitCount_Call {"); - WLog_DBG(TAG, " szLookupName=%s", call->szLookupName); + WLog_LVL(TAG, g_LogLevel, " szLookupName=%s", call->szLookupName); smartcard_log_context(TAG, &call->Common.hContext); WLog_DBG( TAG, "..CardIdentifier=%s", smartcard_array_dump(call->Common.CardIdentifier, sizeof(UUID), buffer, sizeof(buffer))); - WLog_DBG(TAG, " FreshnessCounter=%" PRIu32, call->Common.FreshnessCounter); - WLog_DBG(TAG, " fPbDataIsNULL=%" PRId32, call->Common.fPbDataIsNULL); - WLog_DBG(TAG, " cbDataLen=%" PRIu32, call->Common.cbDataLen); + WLog_LVL(TAG, g_LogLevel, " FreshnessCounter=%" PRIu32, call->Common.FreshnessCounter); + WLog_LVL(TAG, g_LogLevel, " fPbDataIsNULL=%" PRId32, call->Common.fPbDataIsNULL); + WLog_LVL(TAG, g_LogLevel, " cbDataLen=%" PRIu32, call->Common.cbDataLen); - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, "}"); } static void smartcard_trace_read_cache_w_call(SMARTCARD_DEVICE* smartcard, @@ -714,23 +928,23 @@ static void smartcard_trace_read_cache_w_call(SMARTCARD_DEVICE* smartcard, char* tmp; char buffer[1024]; WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; - WLog_DBG(TAG, "GetTransmitCount_Call {"); + WLog_LVL(TAG, g_LogLevel, "GetTransmitCount_Call {"); ConvertFromUnicode(CP_UTF8, 0, call->szLookupName, -1, &tmp, 0, NULL, NULL); - WLog_DBG(TAG, " szLookupName=%s", tmp); + WLog_LVL(TAG, g_LogLevel, " szLookupName=%s", tmp); free(tmp); smartcard_log_context(TAG, &call->Common.hContext); WLog_DBG( TAG, "..CardIdentifier=%s", smartcard_array_dump(call->Common.CardIdentifier, sizeof(UUID), buffer, sizeof(buffer))); - WLog_DBG(TAG, " FreshnessCounter=%" PRIu32, call->Common.FreshnessCounter); - WLog_DBG(TAG, " fPbDataIsNULL=%" PRId32, call->Common.fPbDataIsNULL); - WLog_DBG(TAG, " cbDataLen=%" PRIu32, call->Common.cbDataLen); + WLog_LVL(TAG, g_LogLevel, " FreshnessCounter=%" PRIu32, call->Common.FreshnessCounter); + WLog_LVL(TAG, g_LogLevel, " fPbDataIsNULL=%" PRId32, call->Common.fPbDataIsNULL); + WLog_LVL(TAG, g_LogLevel, " cbDataLen=%" PRIu32, call->Common.cbDataLen); - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, "}"); } static void smartcard_trace_transmit_call(SMARTCARD_DEVICE* smartcard, const Transmit_Call* call) @@ -739,10 +953,10 @@ static void smartcard_trace_transmit_call(SMARTCARD_DEVICE* smartcard, const Tra BYTE* pbExtraBytes; WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; - WLog_DBG(TAG, "Transmit_Call {"); + WLog_LVL(TAG, g_LogLevel, "Transmit_Call {"); smartcard_log_context(TAG, &call->hContext); smartcard_log_redir_handle(TAG, &call->hCard); @@ -750,56 +964,57 @@ static void smartcard_trace_transmit_call(SMARTCARD_DEVICE* smartcard, const Tra { cbExtraBytes = (UINT32)(call->pioSendPci->cbPciLength - sizeof(SCARD_IO_REQUEST)); pbExtraBytes = &((BYTE*)call->pioSendPci)[sizeof(SCARD_IO_REQUEST)]; - WLog_DBG(TAG, "pioSendPci: dwProtocol: %" PRIu32 " cbExtraBytes: %" PRIu32 "", + WLog_LVL(TAG, g_LogLevel, "pioSendPci: dwProtocol: %" PRIu32 " cbExtraBytes: %" PRIu32 "", call->pioSendPci->dwProtocol, cbExtraBytes); if (cbExtraBytes) { - char* szExtraBytes = winpr_BinToHexString(pbExtraBytes, cbExtraBytes, TRUE); - WLog_DBG(TAG, "pbExtraBytes: %s", szExtraBytes); - free(szExtraBytes); + char buffer[1024]; + WLog_LVL(TAG, g_LogLevel, "pbExtraBytes: %s", + smartcard_array_dump(pbExtraBytes, cbExtraBytes, buffer, sizeof(buffer))); } } else { - WLog_DBG(TAG, "pioSendPci: null"); + WLog_LVL(TAG, g_LogLevel, "pioSendPci: null"); } - WLog_DBG(TAG, "cbSendLength: %" PRIu32 "", call->cbSendLength); + WLog_LVL(TAG, g_LogLevel, "cbSendLength: %" PRIu32 "", call->cbSendLength); if (call->pbSendBuffer) { - char* szSendBuffer = winpr_BinToHexString(call->pbSendBuffer, call->cbSendLength, TRUE); - WLog_DBG(TAG, "pbSendBuffer: %s", szSendBuffer); - free(szSendBuffer); + char buffer[1024]; + WLog_DBG( + TAG, "pbSendBuffer: %s", + smartcard_array_dump(call->pbSendBuffer, call->cbSendLength, buffer, sizeof(buffer))); } else { - WLog_DBG(TAG, "pbSendBuffer: null"); + WLog_LVL(TAG, g_LogLevel, "pbSendBuffer: null"); } if (call->pioRecvPci) { cbExtraBytes = (UINT32)(call->pioRecvPci->cbPciLength - sizeof(SCARD_IO_REQUEST)); pbExtraBytes = &((BYTE*)call->pioRecvPci)[sizeof(SCARD_IO_REQUEST)]; - WLog_DBG(TAG, "pioRecvPci: dwProtocol: %" PRIu32 " cbExtraBytes: %" PRIu32 "", + WLog_LVL(TAG, g_LogLevel, "pioRecvPci: dwProtocol: %" PRIu32 " cbExtraBytes: %" PRIu32 "", call->pioRecvPci->dwProtocol, cbExtraBytes); if (cbExtraBytes) { - char* szExtraBytes = winpr_BinToHexString(pbExtraBytes, cbExtraBytes, TRUE); - WLog_DBG(TAG, "pbExtraBytes: %s", szExtraBytes); - free(szExtraBytes); + char buffer[1024]; + WLog_LVL(TAG, g_LogLevel, "pbExtraBytes: %s", + smartcard_array_dump(pbExtraBytes, cbExtraBytes, buffer, sizeof(buffer))); } } else { - WLog_DBG(TAG, "pioRecvPci: null"); + WLog_LVL(TAG, g_LogLevel, "pioRecvPci: null"); } - WLog_DBG(TAG, "fpbRecvBufferIsNULL: %" PRId32 " cbRecvLength: %" PRIu32 "", + WLog_LVL(TAG, g_LogLevel, "fpbRecvBufferIsNULL: %" PRId32 " cbRecvLength: %" PRIu32 "", call->fpbRecvBufferIsNULL, call->cbRecvLength); - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, "}"); } static void smartcard_trace_locate_cards_by_atr_w_call(SMARTCARD_DEVICE* smartcard, @@ -808,49 +1023,42 @@ static void smartcard_trace_locate_cards_by_atr_w_call(SMARTCARD_DEVICE* smartca UINT32 index; char* szEventState; char* szCurrentState; - char* rgbAtr; + WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; - WLog_DBG(TAG, "LocateCardsByATRW_Call {"); + WLog_LVL(TAG, g_LogLevel, "LocateCardsByATRW_Call {"); smartcard_log_context(TAG, &call->hContext); for (index = 0; index < call->cReaders; index++) { + char buffer[1024]; char* tmp = NULL; const LPSCARD_READERSTATEW readerState = (const LPSCARD_READERSTATEW)&call->rgReaderStates[index]; ConvertFromUnicode(CP_UTF8, 0, readerState->szReader, -1, &tmp, 0, NULL, NULL); - WLog_DBG(TAG, "\t[%" PRIu32 "]: szReader: %s cbAtr: %" PRIu32 "", index, tmp, + WLog_LVL(TAG, g_LogLevel, "\t[%" PRIu32 "]: szReader: %s cbAtr: %" PRIu32 "", index, tmp, readerState->cbAtr); szCurrentState = SCardGetReaderStateString(readerState->dwCurrentState); szEventState = SCardGetReaderStateString(readerState->dwEventState); - rgbAtr = winpr_BinToHexString((BYTE*)&(readerState->rgbAtr), readerState->cbAtr, FALSE); - WLog_DBG(TAG, "\t[%" PRIu32 "]: dwCurrentState: %s (0x%08" PRIX32 ")", index, + WLog_LVL(TAG, g_LogLevel, "\t[%" PRIu32 "]: dwCurrentState: %s (0x%08" PRIX32 ")", index, szCurrentState, readerState->dwCurrentState); - WLog_DBG(TAG, "\t[%" PRIu32 "]: dwEventState: %s (0x%08" PRIX32 ")", index, szEventState, - readerState->dwEventState); + WLog_LVL(TAG, g_LogLevel, "\t[%" PRIu32 "]: dwEventState: %s (0x%08" PRIX32 ")", index, + szEventState, readerState->dwEventState); - if (rgbAtr) - { - WLog_DBG(TAG, "\t[%" PRIu32 "]: cbAtr: %" PRIu32 " rgbAtr: %s", index, - readerState->cbAtr, rgbAtr); - } - else - { - WLog_DBG(TAG, "\t[%" PRIu32 "]: cbAtr: 0 rgbAtr: n/a", index); - } + WLog_DBG( + TAG, "\t[%" PRIu32 "]: cbAtr: %" PRIu32 " rgbAtr: %s", index, readerState->cbAtr, + smartcard_array_dump(readerState->rgbAtr, readerState->cbAtr, buffer, sizeof(buffer))); free(szCurrentState); free(szEventState); - free(rgbAtr); free(tmp); } - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, "}"); } static void smartcard_trace_transmit_return(SMARTCARD_DEVICE* smartcard, const Transmit_Return* ret) @@ -859,86 +1067,88 @@ static void smartcard_trace_transmit_return(SMARTCARD_DEVICE* smartcard, const T BYTE* pbExtraBytes; WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; - WLog_DBG(TAG, "Transmit_Return {"); - WLog_DBG(TAG, "ReturnCode: %s (0x%08" PRIX32 ")", SCardGetErrorString(ret->ReturnCode), - ret->ReturnCode); + WLog_LVL(TAG, g_LogLevel, "Transmit_Return {"); + WLog_LVL(TAG, g_LogLevel, " ReturnCode: %s (0x%08" PRIX32 ")", + SCardGetErrorString(ret->ReturnCode), ret->ReturnCode); if (ret->pioRecvPci) { cbExtraBytes = (UINT32)(ret->pioRecvPci->cbPciLength - sizeof(SCARD_IO_REQUEST)); pbExtraBytes = &((BYTE*)ret->pioRecvPci)[sizeof(SCARD_IO_REQUEST)]; - WLog_DBG(TAG, "pioRecvPci: dwProtocol: %" PRIu32 " cbExtraBytes: %" PRIu32 "", + WLog_LVL(TAG, g_LogLevel, " pioRecvPci: dwProtocol: %" PRIu32 " cbExtraBytes: %" PRIu32 "", ret->pioRecvPci->dwProtocol, cbExtraBytes); if (cbExtraBytes) { - char* szExtraBytes = winpr_BinToHexString(pbExtraBytes, cbExtraBytes, TRUE); - WLog_DBG(TAG, "pbExtraBytes: %s", szExtraBytes); - free(szExtraBytes); + char buffer[1024]; + WLog_LVL(TAG, g_LogLevel, " pbExtraBytes: %s", + smartcard_array_dump(pbExtraBytes, cbExtraBytes, buffer, sizeof(buffer))); } } else { - WLog_DBG(TAG, "pioRecvPci: null"); + WLog_LVL(TAG, g_LogLevel, " pioRecvPci: null"); } - WLog_DBG(TAG, "cbRecvLength: %" PRIu32 "", ret->cbRecvLength); + WLog_LVL(TAG, g_LogLevel, " cbRecvLength: %" PRIu32 "", ret->cbRecvLength); if (ret->pbRecvBuffer) { - char* szRecvBuffer = winpr_BinToHexString(ret->pbRecvBuffer, ret->cbRecvLength, TRUE); - WLog_DBG(TAG, "pbRecvBuffer: %s", szRecvBuffer); - free(szRecvBuffer); + char buffer[1024]; + WLog_DBG( + TAG, " pbRecvBuffer: %s", + smartcard_array_dump(ret->pbRecvBuffer, ret->cbRecvLength, buffer, sizeof(buffer))); } else { - WLog_DBG(TAG, "pbRecvBuffer: null"); + WLog_LVL(TAG, g_LogLevel, " pbRecvBuffer: null"); } - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, "}"); } static void smartcard_trace_control_return(SMARTCARD_DEVICE* smartcard, const Control_Return* ret) { WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; - WLog_DBG(TAG, "Control_Return {"); - WLog_DBG(TAG, "ReturnCode: %s (0x%08" PRIX32 ")", SCardGetErrorString(ret->ReturnCode), - ret->ReturnCode); - WLog_DBG(TAG, "cbOutBufferSize: %" PRIu32 "", ret->cbOutBufferSize); + WLog_LVL(TAG, g_LogLevel, "Control_Return {"); + WLog_LVL(TAG, g_LogLevel, " ReturnCode: %s (0x%08" PRIX32 ")", + SCardGetErrorString(ret->ReturnCode), ret->ReturnCode); + WLog_LVL(TAG, g_LogLevel, " cbOutBufferSize: %" PRIu32 "", ret->cbOutBufferSize); if (ret->pvOutBuffer) { - char* szOutBuffer = winpr_BinToHexString(ret->pvOutBuffer, ret->cbOutBufferSize, TRUE); - WLog_DBG(TAG, "pvOutBuffer: %s", szOutBuffer); - free(szOutBuffer); + char buffer[1024]; + WLog_DBG( + TAG, "pvOutBuffer: %s", + smartcard_array_dump(ret->pvOutBuffer, ret->cbOutBufferSize, buffer, sizeof(buffer))); } else { - WLog_DBG(TAG, "pvOutBuffer: null"); + WLog_LVL(TAG, g_LogLevel, "pvOutBuffer: null"); } - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, "}"); } static void smartcard_trace_control_call(SMARTCARD_DEVICE* smartcard, const Control_Call* call) { WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; - WLog_DBG(TAG, "Control_Call {"); + WLog_LVL(TAG, g_LogLevel, "Control_Call {"); smartcard_log_context(TAG, &call->hContext); smartcard_log_redir_handle(TAG, &call->hCard); - WLog_DBG(TAG, + WLog_LVL(TAG, g_LogLevel, "dwControlCode: 0x%08" PRIX32 " cbInBufferSize: %" PRIu32 " fpvOutBufferIsNULL: %" PRId32 " cbOutBufferSize: %" PRIu32 "", call->dwControlCode, call->cbInBufferSize, call->fpvOutBufferIsNULL, @@ -946,16 +1156,17 @@ static void smartcard_trace_control_call(SMARTCARD_DEVICE* smartcard, const Cont if (call->pvInBuffer) { - char* szInBuffer = winpr_BinToHexString(call->pvInBuffer, call->cbInBufferSize, TRUE); - WLog_DBG(TAG, "pbInBuffer: %s", szInBuffer); - free(szInBuffer); + char buffer[1024]; + WLog_DBG( + TAG, "pbInBuffer: %s", + smartcard_array_dump(call->pvInBuffer, call->cbInBufferSize, buffer, sizeof(buffer))); } else { - WLog_DBG(TAG, "pvInBuffer: null"); + WLog_LVL(TAG, g_LogLevel, "pvInBuffer: null"); } - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, "}"); } static void smartcard_trace_set_attrib_call(SMARTCARD_DEVICE* smartcard, const SetAttrib_Call* call) @@ -963,17 +1174,17 @@ static void smartcard_trace_set_attrib_call(SMARTCARD_DEVICE* smartcard, const S char buffer[8192]; WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; - WLog_DBG(TAG, "GetAttrib_Call {"); + WLog_LVL(TAG, g_LogLevel, "GetAttrib_Call {"); smartcard_log_context(TAG, &call->hContext); smartcard_log_redir_handle(TAG, &call->hCard); - WLog_DBG(TAG, "dwAttrId: 0x%08" PRIX32, call->dwAttrId); - WLog_DBG(TAG, "cbAttrLen: 0x%08" PRId32, call->cbAttrLen); - WLog_DBG(TAG, "pbAttr: %s", + WLog_LVL(TAG, g_LogLevel, "dwAttrId: 0x%08" PRIX32, call->dwAttrId); + WLog_LVL(TAG, g_LogLevel, "cbAttrLen: 0x%08" PRId32, call->cbAttrLen); + WLog_LVL(TAG, g_LogLevel, "pbAttr: %s", smartcard_array_dump(call->pbAttr, call->cbAttrLen, buffer, sizeof(buffer))); - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, "}"); } static void smartcard_trace_get_attrib_return(SMARTCARD_DEVICE* smartcard, @@ -981,45 +1192,49 @@ static void smartcard_trace_get_attrib_return(SMARTCARD_DEVICE* smartcard, { WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; - WLog_DBG(TAG, "GetAttrib_Return {"); - WLog_DBG(TAG, "ReturnCode: %s (0x%08" PRIX32 ")", SCardGetErrorString(ret->ReturnCode), - ret->ReturnCode); - WLog_DBG(TAG, "dwAttrId: %s (0x%08" PRIX32 ") cbAttrLen: 0x%08" PRIX32 "", + WLog_LVL(TAG, g_LogLevel, "GetAttrib_Return {"); + WLog_LVL(TAG, g_LogLevel, " ReturnCode: %s (0x%08" PRIX32 ")", + SCardGetErrorString(ret->ReturnCode), ret->ReturnCode); + WLog_LVL(TAG, g_LogLevel, " dwAttrId: %s (0x%08" PRIX32 ") cbAttrLen: 0x%08" PRIX32 "", SCardGetAttributeString(dwAttrId), dwAttrId, ret->cbAttrLen); if (dwAttrId == SCARD_ATTR_VENDOR_NAME) { - WLog_DBG(TAG, "pbAttr: %.*s", ret->cbAttrLen, (char*)ret->pbAttr); + WLog_LVL(TAG, g_LogLevel, " pbAttr: %.*s", ret->cbAttrLen, (char*)ret->pbAttr); } else if (dwAttrId == SCARD_ATTR_CURRENT_PROTOCOL_TYPE) { - UINT32 dwProtocolType = *((UINT32*)ret->pbAttr); - WLog_DBG(TAG, "dwProtocolType: %s (0x%08" PRIX32 ")", - SCardGetProtocolString(dwProtocolType), dwProtocolType); + union { + BYTE* pb; + DWORD* pd; + } attr; + attr.pb = ret->pbAttr; + WLog_LVL(TAG, g_LogLevel, " dwProtocolType: %s (0x%08" PRIX32 ")", + SCardGetProtocolString(*attr.pd), *attr.pd); } - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, "}"); } static void smartcard_trace_get_attrib_call(SMARTCARD_DEVICE* smartcard, const GetAttrib_Call* call) { WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; - WLog_DBG(TAG, "GetAttrib_Call {"); + WLog_LVL(TAG, g_LogLevel, "GetAttrib_Call {"); smartcard_log_context(TAG, &call->hContext); smartcard_log_redir_handle(TAG, &call->hCard); - WLog_DBG(TAG, + WLog_LVL(TAG, g_LogLevel, "dwAttrId: %s (0x%08" PRIX32 ") fpbAttrIsNULL: %" PRId32 " cbAttrLen: 0x%08" PRIX32 "", SCardGetAttributeString(call->dwAttrId), call->dwAttrId, call->fpbAttrIsNULL, call->cbAttrLen); - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, "}"); } static void smartcard_trace_status_call(SMARTCARD_DEVICE* smartcard, const Status_Call* call, @@ -1027,45 +1242,66 @@ static void smartcard_trace_status_call(SMARTCARD_DEVICE* smartcard, const Statu { WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; - WLog_DBG(TAG, "Status%s_Call {", unicode ? "W" : "A"); + WLog_LVL(TAG, g_LogLevel, "Status%s_Call {", unicode ? "W" : "A"); smartcard_log_context(TAG, &call->hContext); smartcard_log_redir_handle(TAG, &call->hCard); - WLog_DBG(TAG, + WLog_LVL(TAG, g_LogLevel, "fmszReaderNamesIsNULL: %" PRId32 " cchReaderLen: %" PRIu32 " cbAtrLen: %" PRIu32 "", call->fmszReaderNamesIsNULL, call->cchReaderLen, call->cbAtrLen); - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, "}"); } static void smartcard_trace_status_return(SMARTCARD_DEVICE* smartcard, const Status_Return* ret, BOOL unicode) { - char* pbAtr = NULL; char* mszReaderNamesA = NULL; + char buffer[1024]; + WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; mszReaderNamesA = smartcard_convert_string_list(ret->mszReaderNames, ret->cBytes, unicode); - pbAtr = winpr_BinToHexString(ret->pbAtr, ret->cbAtrLen, FALSE); - WLog_DBG(TAG, "Status%s_Return {", unicode ? "W" : "A"); - WLog_DBG(TAG, "ReturnCode: %s (0x%08" PRIX32 ")", SCardGetErrorString(ret->ReturnCode), - ret->ReturnCode); - WLog_DBG(TAG, "dwState: %s (0x%08" PRIX32 ") dwProtocol: %s (0x%08" PRIX32 ")", + WLog_LVL(TAG, g_LogLevel, "Status%s_Return {", unicode ? "W" : "A"); + WLog_LVL(TAG, g_LogLevel, " ReturnCode: %s (0x%08" PRIX32 ")", + SCardGetErrorString(ret->ReturnCode), ret->ReturnCode); + WLog_LVL(TAG, g_LogLevel, " dwState: %s (0x%08" PRIX32 ") dwProtocol: %s (0x%08" PRIX32 ")", SCardGetCardStateString(ret->dwState), ret->dwState, SCardGetProtocolString(ret->dwProtocol), ret->dwProtocol); - WLog_DBG(TAG, "cBytes: %" PRIu32 " mszReaderNames: %s", ret->cBytes, mszReaderNamesA); + WLog_LVL(TAG, g_LogLevel, " cBytes: %" PRIu32 " mszReaderNames: %s", ret->cBytes, + mszReaderNamesA); - WLog_DBG(TAG, "cbAtrLen: %" PRIu32 " pbAtr: %s", ret->cbAtrLen, pbAtr); - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, " cbAtrLen: %" PRIu32 " pbAtr: %s", ret->cbAtrLen, + smartcard_array_dump(ret->pbAtr, ret->cbAtrLen, buffer, sizeof(buffer))); + WLog_LVL(TAG, g_LogLevel, "}"); free(mszReaderNamesA); - free(pbAtr); +} + +static void smartcard_trace_state_return(SMARTCARD_DEVICE* smartcard, const State_Return* ret) +{ + char buffer[1024]; + + WINPR_UNUSED(smartcard); + + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) + return; + + WLog_LVL(TAG, g_LogLevel, "Reconnect_Return {"); + WLog_LVL(TAG, g_LogLevel, " ReturnCode: %s (0x%08" PRIX32 ")", + SCardGetErrorString(ret->ReturnCode), ret->ReturnCode); + WLog_LVL(TAG, g_LogLevel, " dwState: %s (0x%08" PRIX32 ")", ret->dwState); + WLog_LVL(TAG, g_LogLevel, " dwProtocol: %s (0x%08" PRIX32 ")", ret->dwProtocol); + WLog_LVL(TAG, g_LogLevel, " cbAtrLen: %s (0x%08" PRIX32 ")", ret->cbAtrLen); + WLog_LVL(TAG, g_LogLevel, " rgAtr: %s", + smartcard_array_dump(ret->rgAtr, sizeof(ret->rgAtr), buffer, sizeof(buffer))); + WLog_LVL(TAG, g_LogLevel, "}"); } static void smartcard_trace_reconnect_return(SMARTCARD_DEVICE* smartcard, @@ -1073,34 +1309,34 @@ static void smartcard_trace_reconnect_return(SMARTCARD_DEVICE* smartcard, { WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; - WLog_DBG(TAG, "Reconnect_Return {"); - WLog_DBG(TAG, "ReturnCode: %s (0x%08" PRIX32 ")", SCardGetErrorString(ret->ReturnCode), - ret->ReturnCode); - WLog_DBG(TAG, "dwActiveProtocol: %s (0x%08" PRIX32 ")", + WLog_LVL(TAG, g_LogLevel, "Reconnect_Return {"); + WLog_LVL(TAG, g_LogLevel, " ReturnCode: %s (0x%08" PRIX32 ")", + SCardGetErrorString(ret->ReturnCode), ret->ReturnCode); + WLog_LVL(TAG, g_LogLevel, " dwActiveProtocol: %s (0x%08" PRIX32 ")", SCardGetProtocolString(ret->dwActiveProtocol), ret->dwActiveProtocol); - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, "}"); } static void smartcard_trace_connect_a_call(SMARTCARD_DEVICE* smartcard, const ConnectA_Call* call) { WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; - WLog_DBG(TAG, "ConnectA_Call {"); + WLog_LVL(TAG, g_LogLevel, "ConnectA_Call {"); smartcard_log_context(TAG, &call->Common.hContext); - WLog_DBG(TAG, + WLog_LVL(TAG, g_LogLevel, "szReader: %s dwShareMode: %s (0x%08" PRIX32 ") dwPreferredProtocols: %s (0x%08" PRIX32 ")", call->szReader, SCardGetShareModeString(call->Common.dwShareMode), call->Common.dwShareMode, SCardGetProtocolString(call->Common.dwPreferredProtocols), call->Common.dwPreferredProtocols); - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, "}"); } static void smartcard_trace_connect_w_call(SMARTCARD_DEVICE* smartcard, const ConnectW_Call* call) @@ -1108,20 +1344,20 @@ static void smartcard_trace_connect_w_call(SMARTCARD_DEVICE* smartcard, const Co char* szReaderA = NULL; WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; ConvertFromUnicode(CP_UTF8, 0, call->szReader, -1, &szReaderA, 0, NULL, NULL); - WLog_DBG(TAG, "ConnectW_Call {"); + WLog_LVL(TAG, g_LogLevel, "ConnectW_Call {"); smartcard_log_context(TAG, &call->Common.hContext); - WLog_DBG(TAG, + WLog_LVL(TAG, g_LogLevel, "szReader: %s dwShareMode: %s (0x%08" PRIX32 ") dwPreferredProtocols: %s (0x%08" PRIX32 ")", szReaderA, SCardGetShareModeString(call->Common.dwShareMode), call->Common.dwShareMode, SCardGetProtocolString(call->Common.dwPreferredProtocols), call->Common.dwPreferredProtocols); - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, "}"); free(szReaderA); } @@ -1131,16 +1367,16 @@ static void smartcard_trace_hcard_and_disposition_call(SMARTCARD_DEVICE* smartca { WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; - WLog_DBG(TAG, "%s_Call {", name); + WLog_LVL(TAG, g_LogLevel, "%s_Call {", name); smartcard_log_context(TAG, &call->hContext); smartcard_log_redir_handle(TAG, &call->hCard); - WLog_DBG(TAG, "dwDisposition: %s (0x%08" PRIX32 ")", + WLog_LVL(TAG, g_LogLevel, "dwDisposition: %s (0x%08" PRIX32 ")", SCardGetDispositionString(call->dwDisposition), call->dwDisposition); - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, "}"); } static void smartcard_trace_establish_context_call(SMARTCARD_DEVICE* smartcard, @@ -1148,13 +1384,13 @@ static void smartcard_trace_establish_context_call(SMARTCARD_DEVICE* smartcard, { WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; - WLog_DBG(TAG, "EstablishContext_Call {"); - WLog_DBG(TAG, "dwScope: %s (0x%08" PRIX32 ")", SCardGetScopeString(call->dwScope), + WLog_LVL(TAG, g_LogLevel, "EstablishContext_Call {"); + WLog_LVL(TAG, g_LogLevel, "dwScope: %s (0x%08" PRIX32 ")", SCardGetScopeString(call->dwScope), call->dwScope); - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, "}"); } static void smartcard_trace_establish_context_return(SMARTCARD_DEVICE* smartcard, @@ -1162,15 +1398,15 @@ static void smartcard_trace_establish_context_return(SMARTCARD_DEVICE* smartcard { WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; - WLog_DBG(TAG, "EstablishContext_Return {"); - WLog_DBG(TAG, "ReturnCode: %s (0x%08" PRIX32 ")", SCardGetErrorString(ret->ReturnCode), - ret->ReturnCode); + WLog_LVL(TAG, g_LogLevel, "EstablishContext_Return {"); + WLog_LVL(TAG, g_LogLevel, " ReturnCode: %s (0x%08" PRIX32 ")", + SCardGetErrorString(ret->ReturnCode), ret->ReturnCode); smartcard_log_context(TAG, &ret->hContext); - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, "}"); } void smartcard_trace_long_return(SMARTCARD_DEVICE* smartcard, const Long_Return* ret, @@ -1178,51 +1414,51 @@ void smartcard_trace_long_return(SMARTCARD_DEVICE* smartcard, const Long_Return* { WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; - WLog_DBG(TAG, "%s_Return {", name); - WLog_DBG(TAG, "ReturnCode: %s (0x%08" PRIX32 ")", SCardGetErrorString(ret->ReturnCode), - ret->ReturnCode); - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, "%s_Return {", name); + WLog_LVL(TAG, g_LogLevel, " ReturnCode: %s (0x%08" PRIX32 ")", + SCardGetErrorString(ret->ReturnCode), ret->ReturnCode); + WLog_LVL(TAG, g_LogLevel, "}"); } -void smartcard_trace_connect_return(SMARTCARD_DEVICE* smartcard, const Connect_Return* ret) +static void smartcard_trace_connect_return(SMARTCARD_DEVICE* smartcard, const Connect_Return* ret) { WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; - WLog_DBG(TAG, "Connect_Return {"); - WLog_DBG(TAG, "ReturnCode: %s (0x%08" PRIX32 ")", SCardGetErrorString(ret->ReturnCode), - ret->ReturnCode); + WLog_LVL(TAG, g_LogLevel, "Connect_Return {"); + WLog_LVL(TAG, g_LogLevel, " ReturnCode: %s (0x%08" PRIX32 ")", + SCardGetErrorString(ret->ReturnCode), ret->ReturnCode); smartcard_log_context(TAG, &ret->hContext); smartcard_log_redir_handle(TAG, &ret->hCard); - WLog_DBG(TAG, "dwActiveProtocol: %s (0x%08" PRIX32 ")", + WLog_LVL(TAG, g_LogLevel, " dwActiveProtocol: %s (0x%08" PRIX32 ")", SCardGetProtocolString(ret->dwActiveProtocol), ret->dwActiveProtocol); - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, "}"); } void smartcard_trace_reconnect_call(SMARTCARD_DEVICE* smartcard, const Reconnect_Call* call) { WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; - WLog_DBG(TAG, "Reconnect_Call {"); + WLog_LVL(TAG, g_LogLevel, "Reconnect_Call {"); smartcard_log_context(TAG, &call->hContext); smartcard_log_redir_handle(TAG, &call->hCard); - WLog_DBG(TAG, + WLog_LVL(TAG, g_LogLevel, "dwShareMode: %s (0x%08" PRIX32 ") dwPreferredProtocols: %s (0x%08" PRIX32 ") dwInitialization: %s (0x%08" PRIX32 ")", SCardGetShareModeString(call->dwShareMode), call->dwShareMode, SCardGetProtocolString(call->dwPreferredProtocols), call->dwPreferredProtocols, SCardGetDispositionString(call->dwInitialization), call->dwInitialization); - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, "}"); } static void smartcard_trace_device_type_id_return(SMARTCARD_DEVICE* smartcard, @@ -1230,15 +1466,15 @@ static void smartcard_trace_device_type_id_return(SMARTCARD_DEVICE* smartcard, { WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; - WLog_DBG(TAG, "GetDeviceTypeId_Return {"); - WLog_DBG(TAG, " ReturnCode: %s (0x%08" PRIX32 ")", SCardGetErrorString(ret->ReturnCode), - ret->ReturnCode); - WLog_DBG(TAG, " dwDeviceId=%08" PRIx32, ret->dwDeviceId); + WLog_LVL(TAG, g_LogLevel, "GetDeviceTypeId_Return {"); + WLog_LVL(TAG, g_LogLevel, " ReturnCode: %s (0x%08" PRIX32 ")", + SCardGetErrorString(ret->ReturnCode), ret->ReturnCode); + WLog_LVL(TAG, g_LogLevel, " dwDeviceId=%08" PRIx32, ret->dwDeviceId); - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, "}"); } static LONG smartcard_unpack_common_context_and_string_a(SMARTCARD_DEVICE* smartcard, wStream* s, @@ -1246,22 +1482,21 @@ static LONG smartcard_unpack_common_context_and_string_a(SMARTCARD_DEVICE* smart CHAR** pszReaderName) { LONG status; - size_t len; - status = smartcard_unpack_redir_scard_context(smartcard, s, phContext); - if (status) + UINT32 index = 0; + status = smartcard_unpack_redir_scard_context(smartcard, s, phContext, &index); + if (status != SCARD_S_SUCCESS) return status; - len = Stream_GetRemainingLength(s); + if (!smartcard_ndr_pointer_read(s, &index, NULL)) + return ERROR_INVALID_DATA; - *pszReaderName = (CHAR*)calloc((len + 1), 1); + status = smartcard_unpack_redir_scard_context_ref(smartcard, s, phContext); + if (status != SCARD_S_SUCCESS) + return status; - if (!*pszReaderName) - { - WLog_WARN(TAG, "GetDeviceTypeId_Call out of memory error (call->szReaderName)"); - return STATUS_NO_MEMORY; - } - - Stream_Read(s, *pszReaderName, len); + status = smartcard_ndr_read_a(s, pszReaderName, NDR_PTR_FULL); + if (status != SCARD_S_SUCCESS) + return status; smartcard_trace_context_and_string_call_a(__FUNCTION__, phContext, *pszReaderName); return SCARD_S_SUCCESS; @@ -1272,22 +1507,22 @@ static LONG smartcard_unpack_common_context_and_string_w(SMARTCARD_DEVICE* smart WCHAR** pszReaderName) { LONG status; - size_t len; - status = smartcard_unpack_redir_scard_context(smartcard, s, phContext); - if (status) + UINT32 index = 0; + + status = smartcard_unpack_redir_scard_context(smartcard, s, phContext, &index); + if (status != SCARD_S_SUCCESS) return status; - len = Stream_GetRemainingLength(s); + if (!smartcard_ndr_pointer_read(s, &index, NULL)) + return ERROR_INVALID_DATA; - *pszReaderName = (WCHAR*)calloc((len + 1), 1); + status = smartcard_unpack_redir_scard_context_ref(smartcard, s, phContext); + if (status != SCARD_S_SUCCESS) + return status; - if (!*pszReaderName) - { - WLog_WARN(TAG, "GetDeviceTypeId_Call out of memory error (call->szReaderName)"); - return STATUS_NO_MEMORY; - } - - Stream_Read_UTF16_String(s, *pszReaderName, len / 2); + status = smartcard_ndr_read_w(s, pszReaderName, NDR_PTR_FULL); + if (status != SCARD_S_SUCCESS) + return status; smartcard_trace_context_and_string_call_w(__FUNCTION__, phContext, *pszReaderName); return SCARD_S_SUCCESS; @@ -1391,10 +1626,10 @@ void smartcard_pack_private_type_header(SMARTCARD_DEVICE* smartcard, wStream* s, Stream_Write_UINT32(s, 0x00000000); /* Filler (4 bytes), should be 0x00000000 */ } -LONG smartcard_unpack_read_size_align(SMARTCARD_DEVICE* smartcard, wStream* s, UINT32 size, +LONG smartcard_unpack_read_size_align(SMARTCARD_DEVICE* smartcard, wStream* s, size_t size, UINT32 alignment) { - UINT32 pad; + size_t pad; WINPR_UNUSED(smartcard); pad = size; size = (size + alignment - 1) & ~(alignment - 1); @@ -1406,10 +1641,10 @@ LONG smartcard_unpack_read_size_align(SMARTCARD_DEVICE* smartcard, wStream* s, U return (LONG)pad; } -LONG smartcard_pack_write_size_align(SMARTCARD_DEVICE* smartcard, wStream* s, UINT32 size, +LONG smartcard_pack_write_size_align(SMARTCARD_DEVICE* smartcard, wStream* s, size_t size, UINT32 alignment) { - UINT32 pad; + size_t pad; WINPR_UNUSED(smartcard); pad = size; size = (size + alignment - 1) & ~(alignment - 1); @@ -1489,11 +1724,14 @@ void smartcard_scard_handle_native_to_redir(SMARTCARD_DEVICE* smartcard, REDIR_S CopyMemory(&(handle->pbHandle), &hCard, handle->cbHandle); } -LONG smartcard_unpack_redir_scard_context(SMARTCARD_DEVICE* smartcard, wStream* s, - REDIR_SCARDCONTEXT* context) +LONG smartcard_unpack_redir_scard_context_(SMARTCARD_DEVICE* smartcard, wStream* s, + REDIR_SCARDCONTEXT* context, UINT32* index, + const char* file, const char* function, int line) { UINT32 pbContextNdrPtr; WINPR_UNUSED(smartcard); + WINPR_UNUSED(file); + ZeroMemory(context, sizeof(REDIR_SCARDCONTEXT)); if (Stream_GetRemainingLength(s) < 4) @@ -1518,7 +1756,8 @@ LONG smartcard_unpack_redir_scard_context(SMARTCARD_DEVICE* smartcard, wStream* return STATUS_INVALID_PARAMETER; } - Stream_Read_UINT32(s, pbContextNdrPtr); /* pbContextNdrPtr (4 bytes) */ + if (!smartcard_ndr_pointer_read_(s, index, &pbContextNdrPtr, file, function, line)) + return ERROR_INVALID_DATA; if (((context->cbContext == 0) && pbContextNdrPtr) || ((context->cbContext != 0) && !pbContextNdrPtr)) @@ -1541,13 +1780,20 @@ LONG smartcard_unpack_redir_scard_context(SMARTCARD_DEVICE* smartcard, wStream* } LONG smartcard_pack_redir_scard_context(SMARTCARD_DEVICE* smartcard, wStream* s, - const REDIR_SCARDCONTEXT* context) + const REDIR_SCARDCONTEXT* context, DWORD* index) { - UINT32 pbContextNdrPtr; + const UINT32 pbContextNdrPtr = 0x00020000 + *index * 4; WINPR_UNUSED(smartcard); - pbContextNdrPtr = (context->cbContext) ? 0x00020001 : 0; - Stream_Write_UINT32(s, context->cbContext); /* cbContext (4 bytes) */ - Stream_Write_UINT32(s, pbContextNdrPtr); /* pbContextNdrPtr (4 bytes) */ + + if (context->cbContext != 0) + { + Stream_Write_UINT32(s, context->cbContext); /* cbContext (4 bytes) */ + Stream_Write_UINT32(s, pbContextNdrPtr); /* pbContextNdrPtr (4 bytes) */ + *index = *index + 1; + } + else + Stream_Zero(s, 8); + return SCARD_S_SUCCESS; } @@ -1611,10 +1857,10 @@ LONG smartcard_pack_redir_scard_context_ref(SMARTCARD_DEVICE* smartcard, wStream return SCARD_S_SUCCESS; } -LONG smartcard_unpack_redir_scard_handle(SMARTCARD_DEVICE* smartcard, wStream* s, - REDIR_SCARDHANDLE* handle) +LONG smartcard_unpack_redir_scard_handle_(SMARTCARD_DEVICE* smartcard, wStream* s, + REDIR_SCARDHANDLE* handle, UINT32* index, + const char* file, const char* function, int line) { - UINT32 pbHandleNdrPtr; WINPR_UNUSED(smartcard); ZeroMemory(handle, sizeof(REDIR_SCARDHANDLE)); @@ -1633,18 +1879,26 @@ LONG smartcard_unpack_redir_scard_handle(SMARTCARD_DEVICE* smartcard, wStream* s return STATUS_BUFFER_TOO_SMALL; } - Stream_Read_UINT32(s, pbHandleNdrPtr); /* NdrPtr (4 bytes) */ + if (!smartcard_ndr_pointer_read_(s, index, NULL, file, function, line)) + return ERROR_INVALID_DATA; + return SCARD_S_SUCCESS; } LONG smartcard_pack_redir_scard_handle(SMARTCARD_DEVICE* smartcard, wStream* s, - const REDIR_SCARDHANDLE* handle) + const REDIR_SCARDHANDLE* handle, DWORD* index) { - UINT32 pbHandleNdrPtr; + const UINT32 pbContextNdrPtr = 0x00020000 + *index * 4; WINPR_UNUSED(smartcard); - pbHandleNdrPtr = (handle->cbHandle) ? 0x00020002 : 0; - Stream_Write_UINT32(s, handle->cbHandle); /* cbHandle (4 bytes) */ - Stream_Write_UINT32(s, pbHandleNdrPtr); /* pbHandleNdrPtr (4 bytes) */ + + if (handle->cbHandle != 0) + { + Stream_Write_UINT32(s, handle->cbHandle); /* cbContext (4 bytes) */ + Stream_Write_UINT32(s, pbContextNdrPtr); /* pbContextNdrPtr (4 bytes) */ + *index = *index + 1; + } + else + Stream_Zero(s, 8); return SCARD_S_SUCCESS; } @@ -1722,28 +1976,26 @@ LONG smartcard_pack_establish_context_return(SMARTCARD_DEVICE* smartcard, wStrea const EstablishContext_Return* ret) { LONG status; + DWORD index = 0; smartcard_trace_establish_context_return(smartcard, ret); - if ((status = smartcard_pack_redir_scard_context(smartcard, s, &(ret->hContext)))) - { - WLog_ERR(TAG, "smartcard_pack_redir_scard_context failed with error %" PRId32 "", status); + if (ret->ReturnCode != SCARD_S_SUCCESS) + return ret->ReturnCode; + + if ((status = smartcard_pack_redir_scard_context(smartcard, s, &(ret->hContext), &index))) return status; - } - if ((status = smartcard_pack_redir_scard_context_ref(smartcard, s, &(ret->hContext)))) - WLog_ERR(TAG, "smartcard_pack_redir_scard_context_ref failed with error %" PRId32 "", - status); - - return status; + return smartcard_pack_redir_scard_context_ref(smartcard, s, &(ret->hContext)); } LONG smartcard_unpack_context_call(SMARTCARD_DEVICE* smartcard, wStream* s, Context_Call* call, const char* name) { LONG status; + UINT32 index = 0; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext)); - if (status) + status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext), &index); + if (status != SCARD_S_SUCCESS) return status; if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->hContext)))) @@ -1758,14 +2010,15 @@ LONG smartcard_unpack_list_reader_groups_call(SMARTCARD_DEVICE* smartcard, wStre ListReaderGroups_Call* call, BOOL unicode) { LONG status; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext)); + UINT32 index = 0; + status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext), &index); - if (status) + if (status != SCARD_S_SUCCESS) return status; if (Stream_GetRemainingLength(s) < 8) { - WLog_WARN(TAG, "ListReaderGroups_Call is too short: %d", (int)Stream_GetRemainingLength(s)); + WLog_WARN(TAG, "ListReaderGroups_Call is too short: %" PRIdz, Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } @@ -1773,7 +2026,7 @@ LONG smartcard_unpack_list_reader_groups_call(SMARTCARD_DEVICE* smartcard, wStre Stream_Read_UINT32(s, call->cchGroups); /* cchGroups (4 bytes) */ status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->hContext)); - if (status) + if (status != SCARD_S_SUCCESS) return status; smartcard_trace_list_reader_groups_call(smartcard, call, unicode); @@ -1781,41 +2034,36 @@ LONG smartcard_unpack_list_reader_groups_call(SMARTCARD_DEVICE* smartcard, wStre } LONG smartcard_pack_list_reader_groups_return(SMARTCARD_DEVICE* smartcard, wStream* s, - const ListReaderGroups_Return* ret) + const ListReaderGroups_Return* ret, BOOL unicode) { - UINT32 mszNdrPtr; - smartcard_trace_list_reader_groups_return(smartcard, ret, FALSE); + DWORD index = 0; + UINT32 size = unicode ? sizeof(WCHAR) : sizeof(CHAR); + size *= ret->cBytes; - mszNdrPtr = (ret->cBytes) ? 0x00020008 : 0; - Stream_EnsureRemainingCapacity(s, ret->cBytes + 32); - Stream_Write_UINT32(s, ret->cBytes); /* cBytes (4 bytes) */ - Stream_Write_UINT32(s, mszNdrPtr); /* mszNdrPtr (4 bytes) */ + smartcard_trace_list_reader_groups_return(smartcard, ret, unicode); + if (ret->ReturnCode != SCARD_S_SUCCESS) + return ret->ReturnCode; - if (mszNdrPtr) - { - Stream_Write_UINT32(s, ret->cBytes); /* mszNdrLen (4 bytes) */ + if (!Stream_EnsureRemainingCapacity(s, 4)) + return SCARD_E_NO_MEMORY; - if (ret->msz) - Stream_Write(s, ret->msz, ret->cBytes); - else - Stream_Zero(s, ret->cBytes); + Stream_Write_UINT32(s, size); /* cBytes (4 bytes) */ + if (!smartcard_ndr_pointer_write(s, &index, size)) + return SCARD_E_NO_MEMORY; - smartcard_pack_write_size_align(smartcard, s, ret->cBytes, 4); - } - - return SCARD_S_SUCCESS; + return smartcard_ndr_write(s, ret->msz, size, 1, NDR_PTR_SIMPLE); } LONG smartcard_unpack_list_readers_call(SMARTCARD_DEVICE* smartcard, wStream* s, ListReaders_Call* call, BOOL unicode) { LONG status; - UINT32 count; + UINT32 index = 0; UINT32 mszGroupsNdrPtr; call->mszGroups = NULL; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext)); - if (status) + status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext), &index); + if (status != SCARD_S_SUCCESS) return status; if (Stream_GetRemainingLength(s) < 16) @@ -1824,58 +2072,20 @@ LONG smartcard_unpack_list_readers_call(SMARTCARD_DEVICE* smartcard, wStream* s, return STATUS_BUFFER_TOO_SMALL; } - Stream_Read_UINT32(s, call->cBytes); /* cBytes (4 bytes) */ - Stream_Read_UINT32(s, mszGroupsNdrPtr); /* mszGroupsNdrPtr (4 bytes) */ + Stream_Read_UINT32(s, call->cBytes); /* cBytes (4 bytes) */ + if (!smartcard_ndr_pointer_read(s, &index, &mszGroupsNdrPtr)) + return ERROR_INVALID_DATA; Stream_Read_INT32(s, call->fmszReadersIsNULL); /* fmszReadersIsNULL (4 bytes) */ Stream_Read_UINT32(s, call->cchReaders); /* cchReaders (4 bytes) */ if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->hContext)))) - { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %" PRId32 "", - status); return status; - } - - if ((mszGroupsNdrPtr && !call->cBytes) || (!mszGroupsNdrPtr && call->cBytes)) - { - WLog_WARN(TAG, - "ListReaders_Call mszGroupsNdrPtr (0x%08" PRIX32 ") and cBytes (0x%08" PRIX32 - ") inconsistency", - mszGroupsNdrPtr, call->cBytes); - return STATUS_INVALID_PARAMETER; - } if (mszGroupsNdrPtr) { - Stream_Read_UINT32(s, count); /* NdrCount (4 bytes) */ - - if (count != call->cBytes) - { - WLog_WARN(TAG, - "ListReaders_Call NdrCount (0x%08" PRIX32 ") and cBytes (0x%08" PRIX32 - ") inconsistency", - count, call->cBytes); - return STATUS_INVALID_PARAMETER; - } - - if (Stream_GetRemainingLength(s) < call->cBytes) - { - WLog_WARN(TAG, - "ListReaders_Call is too short: Actual: %" PRIuz ", Expected: %" PRIu32 "", - Stream_GetRemainingLength(s), call->cBytes); - return STATUS_BUFFER_TOO_SMALL; - } - - call->mszGroups = (BYTE*)calloc(1, call->cBytes + 4); - - if (!call->mszGroups) - { - WLog_WARN(TAG, "ListReaders_Call out of memory error (mszGroups)"); - return STATUS_NO_MEMORY; - } - - Stream_Read(s, call->mszGroups, call->cBytes); - smartcard_unpack_read_size_align(smartcard, s, call->cBytes, 4); + status = smartcard_ndr_read(s, &call->mszGroups, call->cBytes, 1, NDR_PTR_SIMPLE); + if (status != SCARD_S_SUCCESS) + return status; } smartcard_trace_list_readers_call(smartcard, call, unicode); @@ -1885,58 +2095,43 @@ LONG smartcard_unpack_list_readers_call(SMARTCARD_DEVICE* smartcard, wStream* s, LONG smartcard_pack_list_readers_return(SMARTCARD_DEVICE* smartcard, wStream* s, const ListReaders_Return* ret, BOOL unicode) { - UINT32 mszNdrPtr; - LONG error; + DWORD index = 0; + UINT32 size = unicode ? sizeof(WCHAR) : sizeof(CHAR); + + size *= ret->cBytes; smartcard_trace_list_readers_return(smartcard, ret, unicode); if (ret->ReturnCode != SCARD_S_SUCCESS) return ret->ReturnCode; - mszNdrPtr = (ret->cBytes) ? 0x00020008 : 0; - - if (!Stream_EnsureRemainingCapacity(s, ret->cBytes + 32)) + if (!Stream_EnsureRemainingCapacity(s, 4)) { WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); return SCARD_F_INTERNAL_ERROR; } - Stream_Write_UINT32(s, ret->cBytes); /* cBytes (4 bytes) */ - Stream_Write_UINT32(s, mszNdrPtr); /* mszNdrPtr (4 bytes) */ + Stream_Write_UINT32(s, size); /* cBytes (4 bytes) */ + if (!smartcard_ndr_pointer_write(s, &index, size)) + return SCARD_E_NO_MEMORY; - if (mszNdrPtr) - { - Stream_Write_UINT32(s, ret->cBytes); /* mszNdrLen (4 bytes) */ - - if (ret->msz) - Stream_Write(s, ret->msz, ret->cBytes); - else - Stream_Zero(s, ret->cBytes); - - if ((error = smartcard_pack_write_size_align(smartcard, s, ret->cBytes, 4))) - { - WLog_ERR(TAG, "smartcard_pack_write_size_align failed with error %" PRId32 "", error); - return error; - } - } - - return SCARD_S_SUCCESS; + return smartcard_ndr_write(s, ret->msz, size, 1, NDR_PTR_SIMPLE); } static LONG smartcard_unpack_connect_common(SMARTCARD_DEVICE* smartcard, wStream* s, - Connect_Common* common) + Connect_Common* common, UINT32* index) { LONG status; + status = smartcard_unpack_redir_scard_context(smartcard, s, &(common->hContext), index); + if (status != SCARD_S_SUCCESS) + return status; + if (Stream_GetRemainingLength(s) < 8) { WLog_WARN(TAG, "Connect_Common is too short: %" PRIuz "", Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } - status = smartcard_unpack_redir_scard_context(smartcard, s, &(common->hContext)); - if (status) - return status; - Stream_Read_UINT32(s, common->dwShareMode); /* dwShareMode (4 bytes) */ Stream_Read_UINT32(s, common->dwPreferredProtocols); /* dwPreferredProtocols (4 bytes) */ return SCARD_S_SUCCESS; @@ -1945,38 +2140,21 @@ static LONG smartcard_unpack_connect_common(SMARTCARD_DEVICE* smartcard, wStream LONG smartcard_unpack_connect_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, ConnectA_Call* call) { LONG status; - UINT32 count; + UINT32 index = 0; call->szReader = NULL; - if (Stream_GetRemainingLength(s) < 4) - { - WLog_WARN(TAG, "ConnectA_Call is too short: %" PRIuz "", Stream_GetRemainingLength(s)); - return STATUS_BUFFER_TOO_SMALL; - } + if (!smartcard_ndr_pointer_read(s, &index, NULL)) + return ERROR_INVALID_DATA; - Stream_Seek_UINT32(s); /* szReaderNdrPtr (4 bytes) */ - - if ((status = smartcard_unpack_connect_common(smartcard, s, &(call->Common)))) + if ((status = smartcard_unpack_connect_common(smartcard, s, &(call->Common), &index))) { WLog_ERR(TAG, "smartcard_unpack_connect_common failed with error %" PRId32 "", status); return status; } - /* szReader */ - Stream_Seek_UINT32(s); /* NdrMaxCount (4 bytes) */ - Stream_Seek_UINT32(s); /* NdrOffset (4 bytes) */ - Stream_Read_UINT32(s, count); /* NdrActualCount (4 bytes) */ - call->szReader = (unsigned char*)malloc(count + 1); - - if (!call->szReader) - { - WLog_WARN(TAG, "ConnectA_Call out of memory error (call->szReader)"); - return STATUS_NO_MEMORY; - } - - Stream_Read(s, call->szReader, count); - smartcard_unpack_read_size_align(smartcard, s, count, 4); - call->szReader[count] = '\0'; + status = smartcard_ndr_read_a(s, &call->szReader, NDR_PTR_FULL); + if (status != SCARD_S_SUCCESS) + return status; if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->Common.hContext)))) WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %" PRId32 "", @@ -1989,38 +2167,22 @@ LONG smartcard_unpack_connect_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, Co LONG smartcard_unpack_connect_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, ConnectW_Call* call) { LONG status; - UINT32 count; + UINT32 index = 0; + call->szReader = NULL; - if (Stream_GetRemainingLength(s) < 4) - { - WLog_WARN(TAG, "ConnectW_Call is too short: %" PRIuz "", Stream_GetRemainingLength(s)); - return STATUS_BUFFER_TOO_SMALL; - } + if (!smartcard_ndr_pointer_read(s, &index, NULL)) + return ERROR_INVALID_DATA; - Stream_Seek_UINT32(s); /* szReaderNdrPtr (4 bytes) */ - - if ((status = smartcard_unpack_connect_common(smartcard, s, &(call->Common)))) + if ((status = smartcard_unpack_connect_common(smartcard, s, &(call->Common), &index))) { WLog_ERR(TAG, "smartcard_unpack_connect_common failed with error %" PRId32 "", status); return status; } - /* szReader */ - Stream_Seek_UINT32(s); /* NdrMaxCount (4 bytes) */ - Stream_Seek_UINT32(s); /* NdrOffset (4 bytes) */ - Stream_Read_UINT32(s, count); /* NdrActualCount (4 bytes) */ - call->szReader = (WCHAR*)calloc((count + 1), 2); - - if (!call->szReader) - { - WLog_WARN(TAG, "ConnectW_Call out of memory error (call->szReader)"); - return STATUS_NO_MEMORY; - } - - Stream_Read(s, call->szReader, (count * 2)); - smartcard_unpack_read_size_align(smartcard, s, (count * 2), 4); - call->szReader[count] = '\0'; + status = smartcard_ndr_read_w(s, &call->szReader, NDR_PTR_FULL); + if (status != SCARD_S_SUCCESS) + return status; if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->Common.hContext)))) WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %" PRId32 "", @@ -2030,48 +2192,45 @@ LONG smartcard_unpack_connect_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, Co return status; } -LONG smartcard_pack_connect_return(SMARTCARD_DEVICE* smartcard, wStream* s, Connect_Return* ret) +LONG smartcard_pack_connect_return(SMARTCARD_DEVICE* smartcard, wStream* s, + const Connect_Return* ret) { LONG status; + DWORD index = 0; - if ((status = smartcard_pack_redir_scard_context(smartcard, s, &(ret->hContext)))) - { - WLog_ERR(TAG, "smartcard_pack_redir_scard_context failed with error %" PRId32 "", status); - return status; - } + smartcard_trace_connect_return(smartcard, ret); + if (ret->ReturnCode != SCARD_S_SUCCESS) + return ret->ReturnCode; - if ((status = smartcard_pack_redir_scard_handle(smartcard, s, &(ret->hCard)))) - { - WLog_ERR(TAG, "smartcard_pack_redir_scard_handle failed with error %" PRId32 "", status); + status = smartcard_pack_redir_scard_context(smartcard, s, &ret->hContext, &index); + if (status != SCARD_S_SUCCESS) return status; - } + + status = smartcard_pack_redir_scard_handle(smartcard, s, &ret->hCard, &index); + if (status != SCARD_S_SUCCESS) + return status; + + if (!Stream_EnsureRemainingCapacity(s, 4)) + return SCARD_E_NO_MEMORY; Stream_Write_UINT32(s, ret->dwActiveProtocol); /* dwActiveProtocol (4 bytes) */ - - if ((status = smartcard_pack_redir_scard_context_ref(smartcard, s, &(ret->hContext)))) - { - WLog_ERR(TAG, "smartcard_pack_redir_scard_context_ref failed with error %" PRId32 "", - status); + status = smartcard_pack_redir_scard_context_ref(smartcard, s, &ret->hContext); + if (status != SCARD_S_SUCCESS) return status; - } - - if ((status = smartcard_pack_redir_scard_handle_ref(smartcard, s, &(ret->hCard)))) - WLog_ERR(TAG, "smartcard_pack_redir_scard_handle_ref failed with error %" PRId32 "", - status); - - return status; + return smartcard_pack_redir_scard_handle_ref(smartcard, s, &(ret->hCard)); } LONG smartcard_unpack_reconnect_call(SMARTCARD_DEVICE* smartcard, wStream* s, Reconnect_Call* call) { LONG status; + UINT32 index = 0; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext)); - if (status) + status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext), &index); + if (status != SCARD_S_SUCCESS) return status; - status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->hCard)); - if (status) + status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->hCard), &index); + if (status != SCARD_S_SUCCESS) return status; if (Stream_GetRemainingLength(s) < 12) @@ -2102,8 +2261,12 @@ LONG smartcard_unpack_reconnect_call(SMARTCARD_DEVICE* smartcard, wStream* s, Re LONG smartcard_pack_reconnect_return(SMARTCARD_DEVICE* smartcard, wStream* s, const Reconnect_Return* ret) { - WINPR_UNUSED(smartcard); smartcard_trace_reconnect_return(smartcard, ret); + if (ret->ReturnCode != SCARD_S_SUCCESS) + return ret->ReturnCode; + + if (!Stream_EnsureRemainingCapacity(s, 4)) + return SCARD_E_NO_MEMORY; Stream_Write_UINT32(s, ret->dwActiveProtocol); /* dwActiveProtocol (4 bytes) */ return SCARD_S_SUCCESS; } @@ -2112,13 +2275,14 @@ LONG smartcard_unpack_hcard_and_disposition_call(SMARTCARD_DEVICE* smartcard, wS HCardAndDisposition_Call* call, const char* name) { LONG status; + UINT32 index = 0; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext)); - if (status) + status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext), &index); + if (status != SCARD_S_SUCCESS) return status; - status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->hCard)); - if (status) + status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->hCard), &index); + if (status != SCARD_S_SUCCESS) return status; if (Stream_GetRemainingLength(s) < 4) @@ -2131,15 +2295,10 @@ LONG smartcard_unpack_hcard_and_disposition_call(SMARTCARD_DEVICE* smartcard, wS Stream_Read_UINT32(s, call->dwDisposition); /* dwDisposition (4 bytes) */ if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->hContext)))) - { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %" PRId32 "", - status); return status; - } if ((status = smartcard_unpack_redir_scard_handle_ref(smartcard, s, &(call->hCard)))) - WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle_ref failed with error %" PRId32 "", - status); + return status; smartcard_trace_hcard_and_disposition_call(smartcard, call, name); return status; @@ -2154,31 +2313,160 @@ static void smartcard_trace_get_status_change_a_call(SMARTCARD_DEVICE* smartcard LPSCARD_READERSTATEA readerState; WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; - WLog_DBG(TAG, "GetStatusChangeA_Call {"); + WLog_LVL(TAG, g_LogLevel, "GetStatusChangeA_Call {"); smartcard_log_context(TAG, &call->hContext); - WLog_DBG(TAG, "dwTimeOut: 0x%08" PRIX32 " cReaders: %" PRIu32 "", call->dwTimeOut, + WLog_LVL(TAG, g_LogLevel, "dwTimeOut: 0x%08" PRIX32 " cReaders: %" PRIu32 "", call->dwTimeOut, call->cReaders); for (index = 0; index < call->cReaders; index++) { readerState = &call->rgReaderStates[index]; - WLog_DBG(TAG, "\t[%" PRIu32 "]: szReader: %s cbAtr: %" PRIu32 "", index, + WLog_LVL(TAG, g_LogLevel, "\t[%" PRIu32 "]: szReader: %s cbAtr: %" PRIu32 "", index, readerState->szReader, readerState->cbAtr); szCurrentState = SCardGetReaderStateString(readerState->dwCurrentState); szEventState = SCardGetReaderStateString(readerState->dwEventState); - WLog_DBG(TAG, "\t[%" PRIu32 "]: dwCurrentState: %s (0x%08" PRIX32 ")", index, + WLog_LVL(TAG, g_LogLevel, "\t[%" PRIu32 "]: dwCurrentState: %s (0x%08" PRIX32 ")", index, szCurrentState, readerState->dwCurrentState); - WLog_DBG(TAG, "\t[%" PRIu32 "]: dwEventState: %s (0x%08" PRIX32 ")", index, szEventState, - readerState->dwEventState); + WLog_LVL(TAG, g_LogLevel, "\t[%" PRIu32 "]: dwEventState: %s (0x%08" PRIX32 ")", index, + szEventState, readerState->dwEventState); free(szCurrentState); free(szEventState); } - WLog_DBG(TAG, "}"); + WLog_LVL(TAG, g_LogLevel, "}"); +} + +static LONG smartcard_unpack_reader_state_a(wStream* s, LPSCARD_READERSTATEA* ppcReaders, + UINT32 cReaders, UINT32* ptrIndex) +{ + UINT32 index, len; + LONG status = ERROR_INVALID_DATA; + LPSCARD_READERSTATEA rgReaderStates; + + if (Stream_GetRemainingLength(s) < 4) + return status; + + Stream_Read_UINT32(s, len); + if (len != cReaders) + { + WLog_ERR(TAG, "Count mismatch when reading LPSCARD_READERSTATEA"); + return status; + } + rgReaderStates = (LPSCARD_READERSTATEA)calloc(cReaders, sizeof(SCARD_READERSTATEA)); + + if (!rgReaderStates) + return STATUS_NO_MEMORY; + + for (index = 0; index < cReaders; index++) + { + LPSCARD_READERSTATEA readerState = &rgReaderStates[index]; + + if (Stream_GetRemainingLength(s) < 52) + { + WLog_WARN(TAG, "GetStatusChangeA_Call is too short: %" PRIuz "", + Stream_GetRemainingLength(s)); + goto fail; + } + + if (!smartcard_ndr_pointer_read(s, ptrIndex, NULL)) + goto fail; + Stream_Read_UINT32(s, readerState->dwCurrentState); /* dwCurrentState (4 bytes) */ + Stream_Read_UINT32(s, readerState->dwEventState); /* dwEventState (4 bytes) */ + Stream_Read_UINT32(s, readerState->cbAtr); /* cbAtr (4 bytes) */ + Stream_Read(s, readerState->rgbAtr, 36); /* rgbAtr [0..36] (36 bytes) */ + } + + for (index = 0; index < cReaders; index++) + { + LPSCARD_READERSTATEA readerState = &rgReaderStates[index]; + + status = smartcard_ndr_read_a(s, &readerState->szReader, NDR_PTR_FULL); + if (status != SCARD_S_SUCCESS) + goto fail; + } + + *ppcReaders = rgReaderStates; + return SCARD_S_SUCCESS; +fail: + if (rgReaderStates) + { + for (index = 0; index < cReaders; index++) + { + LPSCARD_READERSTATEA readerState = &rgReaderStates[index]; + free(readerState->szReader); + } + } + free(rgReaderStates); + return status; +} + +static LONG smartcard_unpack_reader_state_w(wStream* s, LPSCARD_READERSTATEW* ppcReaders, + UINT32 cReaders, UINT32* ptrIndex) +{ + UINT32 index, len; + LONG status = ERROR_INVALID_DATA; + LPSCARD_READERSTATEW rgReaderStates; + + if (Stream_GetRemainingLength(s) < 4) + return status; + + Stream_Read_UINT32(s, len); + if (len != cReaders) + { + WLog_ERR(TAG, "Count mismatch when reading LPSCARD_READERSTATEW"); + return status; + } + + rgReaderStates = (LPSCARD_READERSTATEW)calloc(cReaders, sizeof(SCARD_READERSTATEW)); + + if (!rgReaderStates) + return STATUS_NO_MEMORY; + + for (index = 0; index < cReaders; index++) + { + LPSCARD_READERSTATEW readerState = &rgReaderStates[index]; + + if (Stream_GetRemainingLength(s) < 52) + { + WLog_WARN(TAG, "GetStatusChangeA_Call is too short: %" PRIuz "", + Stream_GetRemainingLength(s)); + goto fail; + } + + if (!smartcard_ndr_pointer_read(s, ptrIndex, NULL)) + goto fail; + Stream_Read_UINT32(s, readerState->dwCurrentState); /* dwCurrentState (4 bytes) */ + Stream_Read_UINT32(s, readerState->dwEventState); /* dwEventState (4 bytes) */ + Stream_Read_UINT32(s, readerState->cbAtr); /* cbAtr (4 bytes) */ + Stream_Read(s, readerState->rgbAtr, 36); /* rgbAtr [0..36] (36 bytes) */ + } + + for (index = 0; index < cReaders; index++) + { + LPSCARD_READERSTATEW readerState = &rgReaderStates[index]; + + status = smartcard_ndr_read_w(s, &readerState->szReader, NDR_PTR_FULL); + if (status != SCARD_S_SUCCESS) + goto fail; + } + + *ppcReaders = rgReaderStates; + return SCARD_S_SUCCESS; +fail: + if (rgReaderStates) + { + for (index = 0; index < cReaders; index++) + { + LPSCARD_READERSTATEW readerState = &rgReaderStates[index]; + free(readerState->szReader); + } + } + free(rgReaderStates); + return status; } /******************************************************************************/ @@ -2188,18 +2476,13 @@ static void smartcard_trace_get_status_change_a_call(SMARTCARD_DEVICE* smartcard LONG smartcard_unpack_get_status_change_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, GetStatusChangeA_Call* call) { - UINT32 index; - UINT32 count; LONG status; - UINT32 offset; - UINT32 maxCount; - UINT32 szReaderNdrPtr; - UINT32 rgReaderStatesNdrPtr; - LPSCARD_READERSTATEA readerState; + UINT32 ndrPtr; + UINT32 index = 0; call->rgReaderStates = NULL; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext)); - if (status) + status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext), &index); + if (status != SCARD_S_SUCCESS) return status; if (Stream_GetRemainingLength(s) < 12) @@ -2209,105 +2492,19 @@ LONG smartcard_unpack_get_status_change_a_call(SMARTCARD_DEVICE* smartcard, wStr return STATUS_BUFFER_TOO_SMALL; } - Stream_Read_UINT32(s, call->dwTimeOut); /* dwTimeOut (4 bytes) */ - Stream_Read_UINT32(s, call->cReaders); /* cReaders (4 bytes) */ - Stream_Read_UINT32(s, rgReaderStatesNdrPtr); /* rgReaderStatesNdrPtr (4 bytes) */ + Stream_Read_UINT32(s, call->dwTimeOut); /* dwTimeOut (4 bytes) */ + Stream_Read_UINT32(s, call->cReaders); /* cReaders (4 bytes) */ + if (!smartcard_ndr_pointer_read(s, &index, &ndrPtr)) + return ERROR_INVALID_DATA; if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->hContext)))) - { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %" PRId32 "", - status); return status; - } - if (Stream_GetRemainingLength(s) < 4) + if (ndrPtr) { - WLog_WARN(TAG, "GetStatusChangeA_Call is too short: %" PRIuz "", - Stream_GetRemainingLength(s)); - return STATUS_BUFFER_TOO_SMALL; - } - - Stream_Read_UINT32(s, count); /* NdrCount (4 bytes) */ - - if (count != call->cReaders) - { - WLog_WARN(TAG, - "GetStatusChangeA_Call unexpected reader count: Actual: %" PRIu32 - ", Expected: %" PRIu32 "", - count, call->cReaders); - return STATUS_INVALID_PARAMETER; - } - - if (call->cReaders > 0) - { - call->rgReaderStates = - (LPSCARD_READERSTATEA)calloc(call->cReaders, sizeof(SCARD_READERSTATEA)); - - if (!call->rgReaderStates) - { - WLog_WARN(TAG, "GetStatusChangeA_Call out of memory error (call->rgReaderStates)"); - return STATUS_NO_MEMORY; - } - - for (index = 0; index < call->cReaders; index++) - { - readerState = &call->rgReaderStates[index]; - - if (Stream_GetRemainingLength(s) < 52) - { - WLog_WARN(TAG, "GetStatusChangeA_Call is too short: %" PRIuz "", - Stream_GetRemainingLength(s)); - return STATUS_BUFFER_TOO_SMALL; - } - - Stream_Read_UINT32(s, szReaderNdrPtr); /* szReaderNdrPtr (4 bytes) */ - Stream_Read_UINT32(s, readerState->dwCurrentState); /* dwCurrentState (4 bytes) */ - Stream_Read_UINT32(s, readerState->dwEventState); /* dwEventState (4 bytes) */ - Stream_Read_UINT32(s, readerState->cbAtr); /* cbAtr (4 bytes) */ - Stream_Read(s, readerState->rgbAtr, 32); /* rgbAtr [0..32] (32 bytes) */ - Stream_Seek(s, 4); /* rgbAtr [32..36] (4 bytes) */ - } - - for (index = 0; index < call->cReaders; index++) - { - readerState = &call->rgReaderStates[index]; - - if (Stream_GetRemainingLength(s) < 12) - { - WLog_WARN(TAG, "GetStatusChangeA_Call is too short: %" PRIuz "", - Stream_GetRemainingLength(s)); - return STATUS_BUFFER_TOO_SMALL; - } - - Stream_Read_UINT32(s, maxCount); /* NdrMaxCount (4 bytes) */ - Stream_Read_UINT32(s, offset); /* NdrOffset (4 bytes) */ - Stream_Read_UINT32(s, count); /* NdrActualCount (4 bytes) */ - - if (Stream_GetRemainingLength(s) < count) - { - WLog_WARN(TAG, "GetStatusChangeA_Call is too short: %" PRIuz "", - Stream_GetRemainingLength(s)); - return STATUS_BUFFER_TOO_SMALL; - } - - readerState->szReader = (LPSTR)malloc(count + 1); - - if (!readerState->szReader) - { - WLog_WARN(TAG, "GetStatusChangeA_Call out of memory error (readerState->szReader)"); - return STATUS_NO_MEMORY; - } - - Stream_Read(s, (void*)readerState->szReader, count); - smartcard_unpack_read_size_align(smartcard, s, count, 4); - ((char*)readerState->szReader)[count] = '\0'; - - if (!readerState->szReader) - { - WLog_WARN(TAG, "GetStatusChangeA_Call null reader name"); - return STATUS_INVALID_PARAMETER; - } - } + status = smartcard_unpack_reader_state_a(s, &call->rgReaderStates, call->cReaders, &index); + if (status != SCARD_S_SUCCESS) + return status; } smartcard_trace_get_status_change_a_call(smartcard, call); @@ -2317,18 +2514,14 @@ LONG smartcard_unpack_get_status_change_a_call(SMARTCARD_DEVICE* smartcard, wStr LONG smartcard_unpack_get_status_change_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, GetStatusChangeW_Call* call) { - UINT32 index; - UINT32 count; + UINT32 ndrPtr; LONG status; - UINT32 offset; - UINT32 maxCount; - UINT32 szReaderNdrPtr; - UINT32 rgReaderStatesNdrPtr; - LPSCARD_READERSTATEW readerState; + UINT32 index = 0; + call->rgReaderStates = NULL; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext)); - if (status) + status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext), &index); + if (status != SCARD_S_SUCCESS) return status; if (Stream_GetRemainingLength(s) < 12) @@ -2340,94 +2533,17 @@ LONG smartcard_unpack_get_status_change_w_call(SMARTCARD_DEVICE* smartcard, wStr Stream_Read_UINT32(s, call->dwTimeOut); /* dwTimeOut (4 bytes) */ Stream_Read_UINT32(s, call->cReaders); /* cReaders (4 bytes) */ - Stream_Read_UINT32(s, rgReaderStatesNdrPtr); /* rgReaderStatesNdrPtr (4 bytes) */ + if (!smartcard_ndr_pointer_read(s, &index, &ndrPtr)) + return ERROR_INVALID_DATA; if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->hContext)))) - { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %" PRId32 "", - status); return status; - } - if (Stream_GetRemainingLength(s) < 4) + if (ndrPtr) { - WLog_WARN(TAG, "GetStatusChangeW_Call is too short: %" PRIuz "", - Stream_GetRemainingLength(s)); - return STATUS_BUFFER_TOO_SMALL; - } - - Stream_Seek_UINT32(s); /* NdrConformant (4 bytes) */ - - if (call->cReaders > 0) - { - call->rgReaderStates = - (LPSCARD_READERSTATEW)calloc(call->cReaders, sizeof(SCARD_READERSTATEW)); - - if (!call->rgReaderStates) - { - WLog_WARN(TAG, "GetStatusChangeW_Call out of memory error (call->rgReaderStates)"); - return STATUS_NO_MEMORY; - } - - for (index = 0; index < call->cReaders; index++) - { - readerState = &call->rgReaderStates[index]; - - if (Stream_GetRemainingLength(s) < 52) - { - WLog_WARN(TAG, "GetStatusChangeW_Call is too short: %" PRIuz "", - Stream_GetRemainingLength(s)); - return STATUS_BUFFER_TOO_SMALL; - } - - Stream_Read_UINT32(s, szReaderNdrPtr); /* (4 bytes) */ - Stream_Read_UINT32(s, readerState->dwCurrentState); /* dwCurrentState (4 bytes) */ - Stream_Read_UINT32(s, readerState->dwEventState); /* dwEventState (4 bytes) */ - Stream_Read_UINT32(s, readerState->cbAtr); /* cbAtr (4 bytes) */ - Stream_Read(s, readerState->rgbAtr, 32); /* rgbAtr [0..32] (32 bytes) */ - Stream_Seek(s, 4); /* rgbAtr [32..36] (4 bytes) */ - } - - for (index = 0; index < call->cReaders; index++) - { - readerState = &call->rgReaderStates[index]; - - if (Stream_GetRemainingLength(s) < 12) - { - WLog_WARN(TAG, "GetStatusChangeW_Call is too short: %" PRIuz "", - Stream_GetRemainingLength(s)); - return STATUS_BUFFER_TOO_SMALL; - } - - Stream_Read_UINT32(s, maxCount); /* NdrMaxCount (4 bytes) */ - Stream_Read_UINT32(s, offset); /* NdrOffset (4 bytes) */ - Stream_Read_UINT32(s, count); /* NdrActualCount (4 bytes) */ - - if (Stream_GetRemainingLength(s) < (count * 2)) - { - WLog_WARN(TAG, "GetStatusChangeW_Call is too short: %" PRIuz "", - Stream_GetRemainingLength(s)); - return STATUS_BUFFER_TOO_SMALL; - } - - readerState->szReader = (WCHAR*)calloc((count + 1), 2); - - if (!readerState->szReader) - { - WLog_WARN(TAG, "GetStatusChangeW_Call out of memory error (readerState->szReader)"); - return STATUS_NO_MEMORY; - } - - Stream_Read(s, (void*)readerState->szReader, (count * 2)); - smartcard_unpack_read_size_align(smartcard, s, (count * 2), 4); - ((WCHAR*)readerState->szReader)[count] = '\0'; - - if (!readerState->szReader) - { - WLog_WARN(TAG, "GetStatusChangeW_Call null reader name"); - return STATUS_INVALID_PARAMETER; - } - } + status = smartcard_unpack_reader_state_w(s, &call->rgReaderStates, call->cReaders, &index); + if (status != SCARD_S_SUCCESS) + return status; } smartcard_trace_get_status_change_w_call(smartcard, call); @@ -2437,39 +2553,32 @@ LONG smartcard_unpack_get_status_change_w_call(SMARTCARD_DEVICE* smartcard, wStr LONG smartcard_pack_get_status_change_return(SMARTCARD_DEVICE* smartcard, wStream* s, const GetStatusChange_Return* ret, BOOL unicode) { - UINT32 index; - ReaderState_Return* rgReaderState; - WINPR_UNUSED(smartcard); + UINT32 index = 0; smartcard_trace_get_status_change_return(smartcard, ret, unicode); + if (ret->ReturnCode != SCARD_S_SUCCESS) + return ret->ReturnCode; + + if (!Stream_EnsureRemainingCapacity(s, 4)) + return SCARD_E_NO_MEMORY; Stream_Write_UINT32(s, ret->cReaders); /* cReaders (4 bytes) */ - Stream_Write_UINT32(s, 0x00020100); /* rgReaderStatesNdrPtr (4 bytes) */ - Stream_Write_UINT32(s, ret->cReaders); /* rgReaderStatesNdrCount (4 bytes) */ - - for (index = 0; index < ret->cReaders; index++) - { - rgReaderState = &(ret->rgReaderStates[index]); - Stream_Write_UINT32(s, rgReaderState->dwCurrentState); /* dwCurrentState (4 bytes) */ - Stream_Write_UINT32(s, rgReaderState->dwEventState); /* dwEventState (4 bytes) */ - Stream_Write_UINT32(s, rgReaderState->cbAtr); /* cbAtr (4 bytes) */ - Stream_Write(s, rgReaderState->rgbAtr, 32); /* rgbAtr [0..32] (32 bytes) */ - Stream_Zero(s, 4); /* rgbAtr [32..36] (32 bytes) */ - } - - return SCARD_S_SUCCESS; + if (!smartcard_ndr_pointer_write(s, &index, ret->cReaders)) + return SCARD_E_NO_MEMORY; + return smartcard_ndr_write_state(s, ret->rgReaderStates, ret->cReaders, NDR_PTR_SIMPLE); } LONG smartcard_unpack_state_call(SMARTCARD_DEVICE* smartcard, wStream* s, State_Call* call) { LONG status; + UINT32 index = 0; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext)); - if (status) + status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext), &index); + if (status != SCARD_S_SUCCESS) return status; - status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->hCard)); - if (status) + status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->hCard), &index); + if (status != SCARD_S_SUCCESS) return status; if (Stream_GetRemainingLength(s) < 8) @@ -2482,46 +2591,41 @@ LONG smartcard_unpack_state_call(SMARTCARD_DEVICE* smartcard, wStream* s, State_ Stream_Read_UINT32(s, call->cbAtrLen); /* cbAtrLen (4 bytes) */ if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->hContext)))) - { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %" PRId32 "", - status); return status; - } if ((status = smartcard_unpack_redir_scard_handle_ref(smartcard, s, &(call->hCard)))) - WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle_ref failed with error %" PRId32 "", - status); + return status; return status; } LONG smartcard_pack_state_return(SMARTCARD_DEVICE* smartcard, wStream* s, const State_Return* ret) { - LONG status; + DWORD index = 0; + + smartcard_trace_state_return(smartcard, ret); + if (ret->ReturnCode != SCARD_S_SUCCESS) + return ret->ReturnCode; + Stream_Write_UINT32(s, ret->dwState); /* dwState (4 bytes) */ Stream_Write_UINT32(s, ret->dwProtocol); /* dwProtocol (4 bytes) */ Stream_Write_UINT32(s, ret->cbAtrLen); /* cbAtrLen (4 bytes) */ - Stream_Write_UINT32(s, 0x00020020); /* rgAtrNdrPtr (4 bytes) */ - Stream_Write_UINT32(s, ret->cbAtrLen); /* rgAtrLength (4 bytes) */ - Stream_Write(s, ret->rgAtr, ret->cbAtrLen); /* rgAtr */ - - if ((status = smartcard_pack_write_size_align(smartcard, s, ret->cbAtrLen, 4))) - WLog_ERR(TAG, "smartcard_pack_write_size_align failed with error %" PRId32 "", status); - - return status; + if (!smartcard_ndr_pointer_write(s, &index, ret->cbAtrLen)) + return SCARD_E_NO_MEMORY; + return smartcard_ndr_write(s, ret->rgAtr, ret->cbAtrLen, 1, NDR_PTR_SIMPLE); } LONG smartcard_unpack_status_call(SMARTCARD_DEVICE* smartcard, wStream* s, Status_Call* call, BOOL unicode) { LONG status; - - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext)); - if (status) + UINT32 index = 0; + status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext), &index); + if (status != SCARD_S_SUCCESS) return status; - status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->hCard)); - if (status) + status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->hCard), &index); + if (status != SCARD_S_SUCCESS) return status; if (Stream_GetRemainingLength(s) < 12) @@ -2535,15 +2639,10 @@ LONG smartcard_unpack_status_call(SMARTCARD_DEVICE* smartcard, wStream* s, Statu Stream_Read_UINT32(s, call->cbAtrLen); /* cbAtrLen (4 bytes) */ if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->hContext)))) - { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %" PRId32 "", - status); return status; - } if ((status = smartcard_unpack_redir_scard_handle_ref(smartcard, s, &(call->hCard)))) - WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle_ref failed with error %" PRId32 "", - status); + return status; smartcard_trace_status_call(smartcard, call, unicode); return status; @@ -2552,44 +2651,42 @@ LONG smartcard_unpack_status_call(SMARTCARD_DEVICE* smartcard, wStream* s, Statu LONG smartcard_pack_status_return(SMARTCARD_DEVICE* smartcard, wStream* s, const Status_Return* ret, BOOL unicode) { - LONG status; + DWORD index = 0; + UINT32 size = unicode ? sizeof(WCHAR) : sizeof(CHAR); + size *= ret->cBytes; smartcard_trace_status_return(smartcard, ret, unicode); - if (!Stream_EnsureRemainingCapacity(s, ret->cBytes + 64)) - { - WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); - return SCARD_F_INTERNAL_ERROR; - } + if (ret->ReturnCode != SCARD_S_SUCCESS) + return ret->ReturnCode; + + if (!Stream_EnsureRemainingCapacity(s, 4)) + return SCARD_F_INTERNAL_ERROR; + + Stream_Write_UINT32(s, size); /* cBytes (4 bytes) */ + if (!smartcard_ndr_pointer_write(s, &index, size)) + return SCARD_E_NO_MEMORY; + + if (!Stream_EnsureRemainingCapacity(s, 44)) + return SCARD_F_INTERNAL_ERROR; - Stream_Write_UINT32(s, ret->cBytes); /* cBytes (4 bytes) */ - Stream_Write_UINT32(s, 0x00020010); /* mszReaderNamesNdrPtr (4 bytes) */ Stream_Write_UINT32(s, ret->dwState); /* dwState (4 bytes) */ Stream_Write_UINT32(s, ret->dwProtocol); /* dwProtocol (4 bytes) */ - Stream_Write(s, ret->pbAtr, 32); /* pbAtr (32 bytes) */ + Stream_Write(s, ret->pbAtr, sizeof(ret->pbAtr)); /* pbAtr (32 bytes) */ Stream_Write_UINT32(s, ret->cbAtrLen); /* cbAtrLen (4 bytes) */ - Stream_Write_UINT32(s, ret->cBytes); /* mszReaderNamesNdrLen (4 bytes) */ - - if (ret->mszReaderNames) - Stream_Write(s, ret->mszReaderNames, ret->cBytes); - else - Stream_Zero(s, ret->cBytes); - - if ((status = smartcard_pack_write_size_align(smartcard, s, ret->cBytes, 4))) - WLog_ERR(TAG, "smartcard_pack_write_size_align failed with error %" PRId32 "", status); - - return status; + return smartcard_ndr_write(s, ret->mszReaderNames, size, 1, NDR_PTR_SIMPLE); } LONG smartcard_unpack_get_attrib_call(SMARTCARD_DEVICE* smartcard, wStream* s, GetAttrib_Call* call) { LONG status; + UINT32 index = 0; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext)); - if (status) + status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext), &index); + if (status != SCARD_S_SUCCESS) return status; - status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->hCard)); - if (status) + status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->hCard), &index); + if (status != SCARD_S_SUCCESS) return status; if (Stream_GetRemainingLength(s) < 12) @@ -2603,15 +2700,10 @@ LONG smartcard_unpack_get_attrib_call(SMARTCARD_DEVICE* smartcard, wStream* s, G Stream_Read_UINT32(s, call->cbAttrLen); /* cbAttrLen (4 bytes) */ if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->hContext)))) - { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %" PRId32 "", - status); return status; - } if ((status = smartcard_unpack_redir_scard_handle_ref(smartcard, s, &(call->hCard)))) - WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle_ref failed with error %" PRId32 "", - status); + return status; smartcard_trace_get_attrib_call(smartcard, call); return status; @@ -2620,42 +2712,35 @@ LONG smartcard_unpack_get_attrib_call(SMARTCARD_DEVICE* smartcard, wStream* s, G LONG smartcard_pack_get_attrib_return(SMARTCARD_DEVICE* smartcard, wStream* s, const GetAttrib_Return* ret, DWORD dwAttrId) { - LONG status; - + DWORD index = 0; smartcard_trace_get_attrib_return(smartcard, ret, dwAttrId); - if (!Stream_EnsureRemainingCapacity(s, ret->cbAttrLen + 32)) - { - WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); + if (ret->ReturnCode != SCARD_S_SUCCESS) + return ret->ReturnCode; + + if (!Stream_EnsureRemainingCapacity(s, 4)) return SCARD_F_INTERNAL_ERROR; - } Stream_Write_UINT32(s, ret->cbAttrLen); /* cbAttrLen (4 bytes) */ - Stream_Write_UINT32(s, 0x00020080); /* pbAttrNdrPtr (4 bytes) */ - Stream_Write_UINT32(s, ret->cbAttrLen); /* pbAttrNdrCount (4 bytes) */ + if (!smartcard_ndr_pointer_write(s, &index, ret->cbAttrLen)) + return SCARD_E_NO_MEMORY; - if (!ret->pbAttr) - Stream_Zero(s, ret->cbAttrLen); /* pbAttr */ - else - Stream_Write(s, ret->pbAttr, ret->cbAttrLen); /* pbAttr */ - - if ((status = smartcard_pack_write_size_align(smartcard, s, ret->cbAttrLen, 4))) - WLog_ERR(TAG, "smartcard_pack_write_size_align failed with error %" PRId32 "", status); - - return status; + return smartcard_ndr_write(s, ret->pbAttr, ret->cbAttrLen, 1, NDR_PTR_SIMPLE); } LONG smartcard_unpack_control_call(SMARTCARD_DEVICE* smartcard, wStream* s, Control_Call* call) { LONG status; - UINT32 length; + UINT32 index = 0; + UINT32 pvInBufferNdrPtr; + call->pvInBuffer = NULL; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext)); - if (status) + status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext), &index); + if (status != SCARD_S_SUCCESS) return status; - status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->hCard)); - if (status) + status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->hCard), &index); + if (status != SCARD_S_SUCCESS) return status; if (Stream_GetRemainingLength(s) < 20) @@ -2666,50 +2751,22 @@ LONG smartcard_unpack_control_call(SMARTCARD_DEVICE* smartcard, wStream* s, Cont Stream_Read_UINT32(s, call->dwControlCode); /* dwControlCode (4 bytes) */ Stream_Read_UINT32(s, call->cbInBufferSize); /* cbInBufferSize (4 bytes) */ - Stream_Seek_UINT32(s); /* pvInBufferNdrPtr (4 bytes) */ + if (!smartcard_ndr_pointer_read(s, &index, &pvInBufferNdrPtr)) /* pvInBufferNdrPtr (4 bytes) */ + return ERROR_INVALID_DATA; Stream_Read_INT32(s, call->fpvOutBufferIsNULL); /* fpvOutBufferIsNULL (4 bytes) */ Stream_Read_UINT32(s, call->cbOutBufferSize); /* cbOutBufferSize (4 bytes) */ if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->hContext)))) - { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %" PRId32 "", - status); return status; - } if ((status = smartcard_unpack_redir_scard_handle_ref(smartcard, s, &(call->hCard)))) - { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %" PRId32 "", - status); return status; - } - if (call->cbInBufferSize) + if (pvInBufferNdrPtr) { - if (Stream_GetRemainingLength(s) < 4) - { - WLog_WARN(TAG, "Control_Call is too short: %" PRIuz "", Stream_GetRemainingLength(s)); - return STATUS_BUFFER_TOO_SMALL; - } - - Stream_Read_UINT32(s, length); /* Length (4 bytes) */ - - if (Stream_GetRemainingLength(s) < length) - { - WLog_WARN(TAG, "Control_Call is too short: %" PRIuz "", Stream_GetRemainingLength(s)); - return STATUS_BUFFER_TOO_SMALL; - } - - call->pvInBuffer = (BYTE*)malloc(length); - - if (!call->pvInBuffer) - { - WLog_WARN(TAG, "Control_Call out of memory error (call->pvInBuffer)"); - return STATUS_NO_MEMORY; - } - - call->cbInBufferSize = length; - Stream_Read(s, call->pvInBuffer, length); + status = smartcard_ndr_read(s, &call->pvInBuffer, call->cbInBufferSize, 1, NDR_PTR_SIMPLE); + if (status != SCARD_S_SUCCESS) + return status; } smartcard_trace_control_call(smartcard, call); @@ -2719,31 +2776,20 @@ LONG smartcard_unpack_control_call(SMARTCARD_DEVICE* smartcard, wStream* s, Cont LONG smartcard_pack_control_return(SMARTCARD_DEVICE* smartcard, wStream* s, const Control_Return* ret) { - LONG error; + DWORD index = 0; smartcard_trace_control_return(smartcard, ret); - if (!Stream_EnsureRemainingCapacity(s, ret->cbOutBufferSize + 32)) - { - WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); + if (ret->ReturnCode != SCARD_S_SUCCESS) + return ret->ReturnCode; + + if (!Stream_EnsureRemainingCapacity(s, 4)) return SCARD_F_INTERNAL_ERROR; - } Stream_Write_UINT32(s, ret->cbOutBufferSize); /* cbOutBufferSize (4 bytes) */ - Stream_Write_UINT32(s, 0x00020040); /* pvOutBufferPointer (4 bytes) */ - Stream_Write_UINT32(s, ret->cbOutBufferSize); /* pvOutBufferLength (4 bytes) */ + if (!smartcard_ndr_pointer_write(s, &index, ret->cbOutBufferSize)) + return SCARD_E_NO_MEMORY; - if (ret->cbOutBufferSize > 0) - { - Stream_Write(s, ret->pvOutBuffer, ret->cbOutBufferSize); /* pvOutBuffer */ - - if ((error = smartcard_pack_write_size_align(smartcard, s, ret->cbOutBufferSize, 4))) - { - WLog_ERR(TAG, "smartcard_pack_write_size_align failed with error %" PRId32 "", error); - return error; - } - } - - return SCARD_S_SUCCESS; + return smartcard_ndr_write(s, ret->pvOutBuffer, ret->cbOutBufferSize, 1, NDR_PTR_SIMPLE); } LONG smartcard_unpack_transmit_call(SMARTCARD_DEVICE* smartcard, wStream* s, Transmit_Call* call) @@ -2756,16 +2802,17 @@ LONG smartcard_unpack_transmit_call(SMARTCARD_DEVICE* smartcard, wStream* s, Tra UINT32 pioRecvPciNdrPtr; SCardIO_Request ioSendPci; SCardIO_Request ioRecvPci; + UINT32 index = 0; call->pioSendPci = NULL; call->pioRecvPci = NULL; call->pbSendBuffer = NULL; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext)); - if (status) + status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext), &index); + if (status != SCARD_S_SUCCESS) return status; - status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->hCard)); - if (status) + status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->hCard), &index); + if (status != SCARD_S_SUCCESS) return status; if (Stream_GetRemainingLength(s) < 32) @@ -2777,10 +2824,18 @@ LONG smartcard_unpack_transmit_call(SMARTCARD_DEVICE* smartcard, wStream* s, Tra Stream_Read_UINT32(s, ioSendPci.dwProtocol); /* dwProtocol (4 bytes) */ Stream_Read_UINT32(s, ioSendPci.cbExtraBytes); /* cbExtraBytes (4 bytes) */ - Stream_Read_UINT32(s, pbExtraBytesNdrPtr); /* pbExtraBytesNdrPtr (4 bytes) */ + if (!smartcard_ndr_pointer_read(s, &index, + &pbExtraBytesNdrPtr)) /* pbExtraBytesNdrPtr (4 bytes) */ + return ERROR_INVALID_DATA; + Stream_Read_UINT32(s, call->cbSendLength); /* cbSendLength (4 bytes) */ - Stream_Read_UINT32(s, pbSendBufferNdrPtr); /* pbSendBufferNdrPtr (4 bytes) */ - Stream_Read_UINT32(s, pioRecvPciNdrPtr); /* pioRecvPciNdrPtr (4 bytes) */ + if (!smartcard_ndr_pointer_read(s, &index, + &pbSendBufferNdrPtr)) /* pbSendBufferNdrPtr (4 bytes) */ + return ERROR_INVALID_DATA; + + if (!smartcard_ndr_pointer_read(s, &index, &pioRecvPciNdrPtr)) /* pioRecvPciNdrPtr (4 bytes) */ + return ERROR_INVALID_DATA; + Stream_Read_INT32(s, call->fpbRecvBufferIsNULL); /* fpbRecvBufferIsNULL (4 bytes) */ Stream_Read_UINT32(s, call->cbRecvLength); /* cbRecvLength (4 bytes) */ @@ -2800,18 +2855,10 @@ LONG smartcard_unpack_transmit_call(SMARTCARD_DEVICE* smartcard, wStream* s, Tra } if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->hContext)))) - { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %" PRId32 "", - status); return status; - } if ((status = smartcard_unpack_redir_scard_handle_ref(smartcard, s, &(call->hCard)))) - { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle_ref failed with error %" PRId32 "", - status); return status; - } if (ioSendPci.cbExtraBytes && !pbExtraBytesNdrPtr) { @@ -2822,6 +2869,7 @@ LONG smartcard_unpack_transmit_call(SMARTCARD_DEVICE* smartcard, wStream* s, Tra if (pbExtraBytesNdrPtr) { + // TODO: Use unified pointer reading if (Stream_GetRemainingLength(s) < 4) { WLog_WARN(TAG, "Transmit_Call is too short: %" PRIuz " (ioSendPci.pbExtraBytes)", @@ -2872,42 +2920,9 @@ LONG smartcard_unpack_transmit_call(SMARTCARD_DEVICE* smartcard, wStream* s, Tra if (pbSendBufferNdrPtr) { - if (Stream_GetRemainingLength(s) < 4) - { - WLog_WARN(TAG, "Transmit_Call is too short: %" PRIuz "", Stream_GetRemainingLength(s)); - return STATUS_BUFFER_TOO_SMALL; - } - - Stream_Read_UINT32(s, length); /* Length (4 bytes) */ - - if (length != call->cbSendLength) - { - WLog_WARN(TAG, - "Transmit_Call unexpected length: Actual: %" PRIu32 ", Expected: %" PRIu32 - " (cbSendLength)", - length, call->cbSendLength); - return STATUS_INVALID_PARAMETER; - } - - if (Stream_GetRemainingLength(s) < call->cbSendLength) - { - WLog_WARN(TAG, - "Transmit_Call is too short: Actual: %" PRIuz ", Expected: %" PRIu32 - " (cbSendLength)", - Stream_GetRemainingLength(s), call->cbSendLength); - return STATUS_BUFFER_TOO_SMALL; - } - - call->pbSendBuffer = (BYTE*)malloc(call->cbSendLength); - - if (!call->pbSendBuffer) - { - WLog_WARN(TAG, "Transmit_Call out of memory error (pbSendBuffer)"); - return STATUS_NO_MEMORY; - } - - Stream_Read(s, call->pbSendBuffer, call->cbSendLength); - smartcard_unpack_read_size_align(smartcard, s, call->cbSendLength, 4); + status = smartcard_ndr_read(s, &call->pbSendBuffer, call->cbSendLength, 1, NDR_PTR_SIMPLE); + if (status != SCARD_S_SUCCESS) + return status; } if (pioRecvPciNdrPtr) @@ -2921,7 +2936,9 @@ LONG smartcard_unpack_transmit_call(SMARTCARD_DEVICE* smartcard, wStream* s, Tra Stream_Read_UINT32(s, ioRecvPci.dwProtocol); /* dwProtocol (4 bytes) */ Stream_Read_UINT32(s, ioRecvPci.cbExtraBytes); /* cbExtraBytes (4 bytes) */ - Stream_Read_UINT32(s, pbExtraBytesNdrPtr); /* pbExtraBytesNdrPtr (4 bytes) */ + if (!smartcard_ndr_pointer_read(s, &index, + &pbExtraBytesNdrPtr)) /* pbExtraBytesNdrPtr (4 bytes) */ + return ERROR_INVALID_DATA; if (ioRecvPci.cbExtraBytes && !pbExtraBytesNdrPtr) { @@ -2933,6 +2950,7 @@ LONG smartcard_unpack_transmit_call(SMARTCARD_DEVICE* smartcard, wStream* s, Tra if (pbExtraBytesNdrPtr) { + // TODO: Unify ndr pointer reading if (Stream_GetRemainingLength(s) < 4) { WLog_WARN(TAG, "Transmit_Call is too short: %" PRIuz " (ioRecvPci.pbExtraBytes)", @@ -3008,29 +3026,30 @@ LONG smartcard_unpack_transmit_call(SMARTCARD_DEVICE* smartcard, wStream* s, Tra LONG smartcard_pack_transmit_return(SMARTCARD_DEVICE* smartcard, wStream* s, const Transmit_Return* ret) { - UINT32 cbExtraBytes; - BYTE* pbExtraBytes; - UINT32 pioRecvPciNdrPtr; - UINT32 pbRecvBufferNdrPtr; - UINT32 pbExtraBytesNdrPtr; + DWORD index = 0; LONG error; UINT32 cbRecvLength = ret->cbRecvLength; + UINT32 cbRecvPci = ret->pioRecvPci ? ret->pioRecvPci->cbPciLength : 0; smartcard_trace_transmit_return(smartcard, ret); + if (ret->ReturnCode != SCARD_S_SUCCESS) + return ret->ReturnCode; + if (!ret->pbRecvBuffer) cbRecvLength = 0; - pioRecvPciNdrPtr = (ret->pioRecvPci) ? 0x00020000 : 0; - pbRecvBufferNdrPtr = (ret->pbRecvBuffer) ? 0x00020004 : 0; - Stream_Write_UINT32(s, pioRecvPciNdrPtr); /* pioRecvPciNdrPtr (4 bytes) */ - Stream_Write_UINT32(s, cbRecvLength); /* cbRecvLength (4 bytes) */ - Stream_Write_UINT32(s, pbRecvBufferNdrPtr); /* pbRecvBufferNdrPtr (4 bytes) */ + if (!smartcard_ndr_pointer_write(s, &index, cbRecvPci)) + return SCARD_E_NO_MEMORY; + if (!Stream_EnsureRemainingCapacity(s, 4)) + return SCARD_E_NO_MEMORY; + Stream_Write_UINT32(s, cbRecvLength); /* cbRecvLength (4 bytes) */ + if (!smartcard_ndr_pointer_write(s, &index, cbRecvLength)) + return SCARD_E_NO_MEMORY; - if (pioRecvPciNdrPtr) + if (ret->pioRecvPci) { - cbExtraBytes = (UINT32)(ret->pioRecvPci->cbPciLength - sizeof(SCARD_IO_REQUEST)); - pbExtraBytes = &((BYTE*)ret->pioRecvPci)[sizeof(SCARD_IO_REQUEST)]; - pbExtraBytesNdrPtr = cbExtraBytes ? 0x00020008 : 0; + UINT32 cbExtraBytes = (UINT32)(ret->pioRecvPci->cbPciLength - sizeof(SCARD_IO_REQUEST)); + BYTE* pbExtraBytes = &((BYTE*)ret->pioRecvPci)[sizeof(SCARD_IO_REQUEST)]; if (!Stream_EnsureRemainingCapacity(s, cbExtraBytes + 16)) { @@ -3040,58 +3059,27 @@ LONG smartcard_pack_transmit_return(SMARTCARD_DEVICE* smartcard, wStream* s, Stream_Write_UINT32(s, ret->pioRecvPci->dwProtocol); /* dwProtocol (4 bytes) */ Stream_Write_UINT32(s, cbExtraBytes); /* cbExtraBytes (4 bytes) */ - Stream_Write_UINT32(s, pbExtraBytesNdrPtr); /* pbExtraBytesNdrPtr (4 bytes) */ - - if (pbExtraBytesNdrPtr) - { - Stream_Write_UINT32(s, cbExtraBytes); /* Length (4 bytes) */ - Stream_Write(s, pbExtraBytes, cbExtraBytes); - - if ((error = smartcard_pack_write_size_align(smartcard, s, cbExtraBytes, 4))) - { - WLog_ERR(TAG, "smartcard_pack_write_size_align failed with error %" PRId32 "!", - error); - return error; - } - } - } - - if (pbRecvBufferNdrPtr) - { - if (!Stream_EnsureRemainingCapacity(s, ret->cbRecvLength + 16)) - { - WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); - return SCARD_F_INTERNAL_ERROR; - } - - Stream_Write_UINT32(s, ret->cbRecvLength); /* pbRecvBufferNdrLen (4 bytes) */ - Stream_Write(s, ret->pbRecvBuffer, ret->cbRecvLength); - - if ((error = smartcard_pack_write_size_align(smartcard, s, ret->cbRecvLength, 4))) - { - WLog_ERR(TAG, "smartcard_pack_write_size_align failed with error %" PRId32 "!", error); + if (!smartcard_ndr_pointer_write(s, &index, cbExtraBytes)) + return SCARD_E_NO_MEMORY; + error = smartcard_ndr_write(s, pbExtraBytes, cbExtraBytes, 1, NDR_PTR_SIMPLE); + if (error) return error; - } } - return SCARD_S_SUCCESS; + return smartcard_ndr_write(s, ret->pbRecvBuffer, ret->cbRecvLength, 1, NDR_PTR_SIMPLE); } LONG smartcard_unpack_locate_cards_by_atr_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, LocateCardsByATRA_Call* call) { - UINT32 index; - UINT32 count; LONG status; - UINT32 offset; - UINT32 maxCount; - UINT32 szReaderNdrPtr; UINT32 rgReaderStatesNdrPtr; UINT32 rgAtrMasksNdrPtr; + UINT32 index = 0; call->rgReaderStates = NULL; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext)); - if (status) + status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext), &index); + if (status != SCARD_S_SUCCESS) return status; if (Stream_GetRemainingLength(s) < 16) @@ -3102,23 +3090,14 @@ LONG smartcard_unpack_locate_cards_by_atr_a_call(SMARTCARD_DEVICE* smartcard, wS } Stream_Read_UINT32(s, call->cAtrs); - Stream_Read_UINT32(s, rgAtrMasksNdrPtr); - Stream_Read_UINT32(s, call->cReaders); /* cReaders (4 bytes) */ - Stream_Read_UINT32(s, rgReaderStatesNdrPtr); /* rgReaderStatesNdrPtr (4 bytes) */ + if (!smartcard_ndr_pointer_read(s, &index, &rgAtrMasksNdrPtr)) + return ERROR_INVALID_DATA; + Stream_Read_UINT32(s, call->cReaders); /* cReaders (4 bytes) */ + if (!smartcard_ndr_pointer_read(s, &index, &rgReaderStatesNdrPtr)) + return ERROR_INVALID_DATA; if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->hContext)))) - { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %" PRId32 "", - status); return status; - } - - if (Stream_GetRemainingLength(s) < 4) - { - WLog_WARN(TAG, "LocateCardsByATRA_Call is too short: %" PRIuz "", - Stream_GetRemainingLength(s)); - return STATUS_BUFFER_TOO_SMALL; - } if ((rgAtrMasksNdrPtr && !call->cAtrs) || (!rgAtrMasksNdrPtr && call->cAtrs)) { @@ -3131,123 +3110,16 @@ LONG smartcard_unpack_locate_cards_by_atr_a_call(SMARTCARD_DEVICE* smartcard, wS if (rgAtrMasksNdrPtr) { - Stream_Read_UINT32(s, count); - - if (count != call->cAtrs) - { - WLog_WARN(TAG, - "LocateCardsByATRA_Call NdrCount (0x%08" PRIX32 ") and cAtrs (0x%08" PRIX32 - ") inconsistency", - count, call->cAtrs); - return STATUS_INVALID_PARAMETER; - } - - if (Stream_GetRemainingLength(s) < call->cAtrs) - { - WLog_WARN(TAG, - "LocateCardsByATRA_Call is too short: Actual: %" PRIuz ", Expected: %" PRIu32 - "", - Stream_GetRemainingLength(s), call->cAtrs); - return STATUS_BUFFER_TOO_SMALL; - } - - call->rgAtrMasks = (LocateCards_ATRMask*)calloc(call->cAtrs, sizeof(LocateCards_ATRMask)); - - if (!call->rgAtrMasks) - { - WLog_WARN(TAG, "LocateCardsByATRA_Call out of memory error (call->rgAtrMasks)"); - return STATUS_NO_MEMORY; - } - - for (index = 0; index < call->cAtrs; index++) - { - Stream_Read_UINT32(s, call->rgAtrMasks[index].cbAtr); - Stream_Read(s, call->rgAtrMasks[index].rgbAtr, 36); - Stream_Read(s, call->rgAtrMasks[index].rgbMask, 36); - } + status = smartcard_ndr_read_atrmask(s, &call->rgAtrMasks, call->cAtrs, NDR_PTR_SIMPLE); + if (status != SCARD_S_SUCCESS) + return status; } - Stream_Read_UINT32(s, count); - - if (count != call->cReaders) + if (rgReaderStatesNdrPtr) { - WLog_WARN(TAG, - "GetStatusChangeA_Call unexpected reader count: Actual: %" PRIu32 - ", Expected: %" PRIu32 "", - count, call->cReaders); - return STATUS_INVALID_PARAMETER; - } - - if (call->cReaders > 0) - { - call->rgReaderStates = - (SCARD_READERSTATEA*)calloc(call->cReaders, sizeof(SCARD_READERSTATEA)); - - if (!call->rgReaderStates) - { - WLog_WARN(TAG, "LocateCardsByATRA_Call out of memory error (call->rgReaderStates)"); - return STATUS_NO_MEMORY; - } - - for (index = 0; index < call->cReaders; index++) - { - LPSCARD_READERSTATEA readerState = &call->rgReaderStates[index]; - - if (Stream_GetRemainingLength(s) < 52) - { - WLog_WARN(TAG, "LocateCardsByATRA_Call is too short: %" PRIuz "", - Stream_GetRemainingLength(s)); - return STATUS_BUFFER_TOO_SMALL; - } - - Stream_Read_UINT32(s, szReaderNdrPtr); /* szReaderNdrPtr (4 bytes) */ - Stream_Read_UINT32(s, readerState->dwCurrentState); /* dwCurrentState (4 bytes) */ - Stream_Read_UINT32(s, readerState->dwEventState); /* dwEventState (4 bytes) */ - Stream_Read_UINT32(s, readerState->cbAtr); /* cbAtr (4 bytes) */ - Stream_Read(s, readerState->rgbAtr, 32); /* rgbAtr [0..32] (32 bytes) */ - Stream_Seek(s, 4); /* rgbAtr [32..36] (4 bytes) */ - } - - for (index = 0; index < call->cReaders; index++) - { - LPSCARD_READERSTATEA readerState = &call->rgReaderStates[index]; - - if (Stream_GetRemainingLength(s) < 12) - { - WLog_WARN(TAG, "GetStatusChangeA_Call is too short: %" PRIuz "", - Stream_GetRemainingLength(s)); - return STATUS_BUFFER_TOO_SMALL; - } - - Stream_Read_UINT32(s, maxCount); /* NdrMaxCount (4 bytes) */ - Stream_Read_UINT32(s, offset); /* NdrOffset (4 bytes) */ - Stream_Read_UINT32(s, count); /* NdrActualCount (4 bytes) */ - - if (Stream_GetRemainingLength(s) < count) - { - WLog_WARN(TAG, "GetStatusChangeA_Call is too short: %" PRIuz "", - Stream_GetRemainingLength(s)); - return STATUS_BUFFER_TOO_SMALL; - } - - readerState->szReader = (LPSTR)malloc(count + 1); - - if (!readerState->szReader) - { - WLog_WARN(TAG, "GetStatusChangeA_Call out of memory error (readerState->szReader)"); - return STATUS_NO_MEMORY; - } - - Stream_Read(s, (void*)readerState->szReader, count); - smartcard_unpack_read_size_align(smartcard, s, count, 4); - ((char*)readerState->szReader)[count] = '\0'; - - if (!readerState->szReader) - { - WLog_WARN(TAG, "GetStatusChangeA_Call null reader name"); - return STATUS_INVALID_PARAMETER; - } - } + status = smartcard_unpack_reader_state_a(s, &call->rgReaderStates, call->cReaders, &index); + if (status != SCARD_S_SUCCESS) + return status; } smartcard_trace_locate_cards_by_atr_a_call(smartcard, call); @@ -3259,69 +3131,35 @@ LONG smartcard_unpack_context_and_two_strings_a_call(SMARTCARD_DEVICE* smartcard { LONG status; UINT32 sz1NdrPtr, sz2NdrPtr; + UINT32 index = 0; - smartcard_trace_context_and_two_strings_a_call(smartcard, call); - - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext)); - if (status) + status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext), &index); + if (status != SCARD_S_SUCCESS) + return status; + + if (!smartcard_ndr_pointer_read(s, &index, &sz1NdrPtr)) + return ERROR_INVALID_DATA; + if (!smartcard_ndr_pointer_read(s, &index, &sz2NdrPtr)) + return ERROR_INVALID_DATA; + + status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &call->hContext); + if (status != SCARD_S_SUCCESS) return status; - if (Stream_GetRemainingLength(s) < 8) - { - WLog_WARN(TAG, "smartcard_unpack_context_and_two_strings_a_call is too short: %" PRIuz "", - Stream_GetRemainingLength(s)); - return STATUS_BUFFER_TOO_SMALL; - } - Stream_Read_UINT32(s, sz1NdrPtr); - Stream_Read_UINT32(s, sz2NdrPtr); if (sz1NdrPtr) { - UINT32 len; - if (Stream_GetRemainingLength(s) < 4) - { - WLog_WARN(TAG, - "smartcard_unpack_context_and_two_strings_a_call is too short: %" PRIuz "", - Stream_GetRemainingLength(s)); - return STATUS_BUFFER_TOO_SMALL; - } - Stream_Read_UINT32(s, len); - if (Stream_GetRemainingLength(s) < len) - { - WLog_WARN(TAG, - "smartcard_unpack_context_and_two_strings_a_call is too short: %" PRIuz "", - Stream_GetRemainingLength(s)); - return STATUS_BUFFER_TOO_SMALL; - } - call->sz1 = calloc(len + 1, sizeof(CHAR)); - if (!call->sz1) - return STATUS_NO_MEMORY; - Stream_Read(s, call->sz1, len); + status = smartcard_ndr_read_a(s, &call->sz1, NDR_PTR_FULL); + if (status != SCARD_S_SUCCESS) + return status; } if (sz2NdrPtr) { - UINT32 len; - if (Stream_GetRemainingLength(s) < 4) - { - WLog_WARN(TAG, - "smartcard_unpack_context_and_two_strings_a_call is too short: %" PRIuz "", - Stream_GetRemainingLength(s)); - return STATUS_BUFFER_TOO_SMALL; - } - Stream_Read_UINT32(s, len); - if (Stream_GetRemainingLength(s) < len) - { - WLog_WARN(TAG, - "smartcard_unpack_context_and_two_strings_a_call is too short: %" PRIuz "", - Stream_GetRemainingLength(s)); - return STATUS_BUFFER_TOO_SMALL; - } - call->sz2 = calloc(len + 1, sizeof(CHAR)); - if (!call->sz2) - return STATUS_NO_MEMORY; - Stream_Read(s, call->sz2, len); + status = smartcard_ndr_read_a(s, &call->sz2, NDR_PTR_FULL); + if (status != SCARD_S_SUCCESS) + return status; } - - return -1; + smartcard_trace_context_and_two_strings_a_call(smartcard, call); + return SCARD_S_SUCCESS; } LONG smartcard_unpack_context_and_two_strings_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, @@ -3329,138 +3167,73 @@ LONG smartcard_unpack_context_and_two_strings_w_call(SMARTCARD_DEVICE* smartcard { LONG status; UINT32 sz1NdrPtr, sz2NdrPtr; - - smartcard_trace_context_and_two_strings_w_call(smartcard, call); - - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext)); - if (status) + UINT32 index = 0; + status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext), &index); + if (status != SCARD_S_SUCCESS) + return status; + + if (!smartcard_ndr_pointer_read(s, &index, &sz1NdrPtr)) + return ERROR_INVALID_DATA; + if (!smartcard_ndr_pointer_read(s, &index, &sz2NdrPtr)) + return ERROR_INVALID_DATA; + + status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &call->hContext); + if (status != SCARD_S_SUCCESS) return status; - if (Stream_GetRemainingLength(s) < 8) - { - WLog_WARN(TAG, "smartcard_unpack_context_and_two_strings_w_call is too short: %" PRIuz "", - Stream_GetRemainingLength(s)); - return STATUS_BUFFER_TOO_SMALL; - } - Stream_Read_UINT32(s, sz1NdrPtr); - Stream_Read_UINT32(s, sz2NdrPtr); if (sz1NdrPtr) { - UINT32 len; - if (Stream_GetRemainingLength(s) < 4) - { - WLog_WARN(TAG, - "smartcard_unpack_context_and_two_strings_w_call is too short: %" PRIuz "", - Stream_GetRemainingLength(s)); - return STATUS_BUFFER_TOO_SMALL; - } - Stream_Read_UINT32(s, len); - if (Stream_GetRemainingLength(s) < len) - { - WLog_WARN(TAG, - "smartcard_unpack_context_and_two_strings_w_call is too short: %" PRIuz "", - Stream_GetRemainingLength(s)); - return STATUS_BUFFER_TOO_SMALL; - } - call->sz1 = calloc(len + 1, sizeof(WCHAR)); - if (!call->sz1) - return STATUS_NO_MEMORY; - Stream_Read(s, call->sz1, len); + status = smartcard_ndr_read_w(s, &call->sz1, NDR_PTR_FULL); + if (status != SCARD_S_SUCCESS) + return status; } if (sz2NdrPtr) { - UINT32 len; - if (Stream_GetRemainingLength(s) < 4) - { - WLog_WARN(TAG, - "smartcard_unpack_context_and_two_strings_w_call is too short: %" PRIuz "", - Stream_GetRemainingLength(s)); - return STATUS_BUFFER_TOO_SMALL; - } - Stream_Read_UINT32(s, len); - if (Stream_GetRemainingLength(s) < len) - { - WLog_WARN(TAG, - "smartcard_unpack_context_and_two_strings_w_call is too short: %" PRIuz "", - Stream_GetRemainingLength(s)); - return STATUS_BUFFER_TOO_SMALL; - } - call->sz2 = calloc(len + 1, sizeof(WCHAR)); - if (!call->sz2) - return STATUS_NO_MEMORY; - Stream_Read(s, call->sz2, len); + status = smartcard_ndr_read_w(s, &call->sz2, NDR_PTR_FULL); + if (status != SCARD_S_SUCCESS) + return status; } + smartcard_trace_context_and_two_strings_w_call(smartcard, call); return SCARD_S_SUCCESS; } LONG smartcard_unpack_locate_cards_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, LocateCardsA_Call* call) { - LONG status; UINT32 sz1NdrPtr, sz2NdrPtr; - - smartcard_trace_locate_cards_a_call(smartcard, call); - - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext)); - if (status) + UINT32 index = 0; + status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext), &index); + if (status != SCARD_S_SUCCESS) return status; - if (Stream_GetRemainingLength(s) < 8) + if (Stream_GetRemainingLength(s) < 16) { WLog_WARN(TAG, "%s is too short: %" PRIuz "", __FUNCTION__, Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } Stream_Read_UINT32(s, call->cBytes); - Stream_Read_UINT32(s, sz1NdrPtr); + if (!smartcard_ndr_pointer_read(s, &index, &sz1NdrPtr)) + return ERROR_INVALID_DATA; + Stream_Read_UINT32(s, call->cReaders); - Stream_Read_UINT32(s, sz2NdrPtr); + if (!smartcard_ndr_pointer_read(s, &index, &sz2NdrPtr)) + return ERROR_INVALID_DATA; + if (sz1NdrPtr) { - UINT32 len; - if (Stream_GetRemainingLength(s) < 4) - { - WLog_WARN(TAG, - "smartcard_unpack_context_and_two_strings_w_call is too short: %" PRIuz "", - Stream_GetRemainingLength(s)); - return STATUS_BUFFER_TOO_SMALL; - } - Stream_Read_UINT32(s, len); - if (Stream_GetRemainingLength(s) < len) - { - WLog_WARN(TAG, - "smartcard_unpack_context_and_two_strings_w_call is too short: %" PRIuz "", - Stream_GetRemainingLength(s)); - return STATUS_BUFFER_TOO_SMALL; - } - call->mszCards = calloc(len + 1, sizeof(CHAR)); - if (!call->mszCards) - return STATUS_NO_MEMORY; - Stream_Read(s, call->mszCards, len); + status = + smartcard_ndr_read_fixed_string_a(s, &call->mszCards, call->cBytes, NDR_PTR_SIMPLE); + if (status != SCARD_S_SUCCESS) + return status; } if (sz2NdrPtr) { - UINT32 len; - if (Stream_GetRemainingLength(s) < 4) - { - WLog_WARN(TAG, "%s is too short: %" PRIuz "", __FUNCTION__, - Stream_GetRemainingLength(s)); - return STATUS_BUFFER_TOO_SMALL; - } - Stream_Read_UINT32(s, len); - if (Stream_GetRemainingLength(s) < len) - { - WLog_WARN(TAG, "%s is too short: %" PRIuz "", __FUNCTION__, - Stream_GetRemainingLength(s)); - return STATUS_BUFFER_TOO_SMALL; - } - call->rgReaderStates = - calloc(len / sizeof(SCARD_READERSTATEA) + 1, sizeof(SCARD_READERSTATEA)); - if (!call->rgReaderStates) - return STATUS_NO_MEMORY; - - Stream_Read(s, call->rgReaderStates, len); + status = smartcard_unpack_reader_state_a(s, &call->rgReaderStates, call->cReaders, &index); + if (status != SCARD_S_SUCCESS) + return status; } + smartcard_trace_locate_cards_a_call(smartcard, call); return SCARD_S_SUCCESS; } @@ -3469,134 +3242,92 @@ LONG smartcard_unpack_locate_cards_w_call(SMARTCARD_DEVICE* smartcard, wStream* { LONG status; UINT32 sz1NdrPtr, sz2NdrPtr; + UINT32 index = 0; - smartcard_trace_locate_cards_w_call(smartcard, call); - - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext)); - if (status) + status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext), &index); + if (status != SCARD_S_SUCCESS) return status; - if (Stream_GetRemainingLength(s) < 8) + if (Stream_GetRemainingLength(s) < 16) { WLog_WARN(TAG, "%s is too short: %" PRIuz "", __FUNCTION__, Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } Stream_Read_UINT32(s, call->cBytes); - Stream_Read_UINT32(s, sz1NdrPtr); + if (!smartcard_ndr_pointer_read(s, &index, &sz1NdrPtr)) + return ERROR_INVALID_DATA; + Stream_Read_UINT32(s, call->cReaders); - Stream_Read_UINT32(s, sz2NdrPtr); + if (!smartcard_ndr_pointer_read(s, &index, &sz2NdrPtr)) + return ERROR_INVALID_DATA; + if (sz1NdrPtr) { - UINT32 len; - if (Stream_GetRemainingLength(s) < 4) - { - WLog_WARN(TAG, "%s is too short: %" PRIuz "", __FUNCTION__, - Stream_GetRemainingLength(s)); - return STATUS_BUFFER_TOO_SMALL; - } - Stream_Read_UINT32(s, len); - if (Stream_GetRemainingLength(s) < len) - { - WLog_WARN(TAG, "%s is too short: %" PRIuz "", __FUNCTION__, - Stream_GetRemainingLength(s)); - return STATUS_BUFFER_TOO_SMALL; - } - call->mszCards = calloc(len + 1, sizeof(WCHAR)); - if (!call->mszCards) - return STATUS_NO_MEMORY; - Stream_Read(s, call->mszCards, len); + status = + smartcard_ndr_read_fixed_string_w(s, &call->mszCards, call->cBytes, NDR_PTR_SIMPLE); + if (status != SCARD_S_SUCCESS) + return status; } if (sz2NdrPtr) { - UINT32 len; - if (Stream_GetRemainingLength(s) < 4) - { - WLog_WARN(TAG, "%s is too short: %" PRIuz "", __FUNCTION__, - Stream_GetRemainingLength(s)); - return STATUS_BUFFER_TOO_SMALL; - } - Stream_Read_UINT32(s, len); - if (Stream_GetRemainingLength(s) < len) - { - WLog_WARN(TAG, "%s is too short: %" PRIuz "", __FUNCTION__, - Stream_GetRemainingLength(s)); - return STATUS_BUFFER_TOO_SMALL; - } - call->rgReaderStates = - calloc(len / sizeof(SCARD_READERSTATEW) + 1, sizeof(SCARD_READERSTATEW)); - if (!call->rgReaderStates) - return STATUS_NO_MEMORY; - - Stream_Read(s, call->rgReaderStates, len); + status = smartcard_unpack_reader_state_w(s, &call->rgReaderStates, call->cReaders, &index); + if (status != SCARD_S_SUCCESS) + return status; } + smartcard_trace_locate_cards_w_call(smartcard, call); return SCARD_S_SUCCESS; } LONG smartcard_unpack_set_attrib_call(SMARTCARD_DEVICE* smartcard, wStream* s, SetAttrib_Call* call) { LONG status; - smartcard_trace_set_attrib_call(smartcard, call); + UINT32 index = 0; + UINT32 ndrPtr; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext)); - if (status) + status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext), &index); + if (status != SCARD_S_SUCCESS) return status; - status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->hCard)); - if (status) + status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->hCard), &index); + if (status != SCARD_S_SUCCESS) return status; if (Stream_GetRemainingLength(s) < 12) return STATUS_BUFFER_TOO_SMALL; Stream_Read_UINT32(s, call->dwAttrId); Stream_Read_UINT32(s, call->cbAttrLen); - if (Stream_GetRemainingLength(s) < call->cbAttrLen) - return STATUS_BUFFER_TOO_SMALL; - call->pbAttr = malloc(call->cbAttrLen); - if (!call->pbAttr) - return STATUS_NO_MEMORY; - Stream_Read(s, call->pbAttr, call->cbAttrLen); - return SCARD_S_SUCCESS; -} + if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->hContext)))) + return status; -LONG smartcard_pack_set_attrib_return(SMARTCARD_DEVICE* smartcard, wStream* s, - const GetAttrib_Return* ret) -{ - LONG error; + if ((status = smartcard_unpack_redir_scard_handle_ref(smartcard, s, &(call->hCard)))) + return status; - if (!Stream_EnsureRemainingCapacity(s, ret->cbAttrLen + 8)) + if (!smartcard_ndr_pointer_read(s, &index, &ndrPtr)) + return ERROR_INVALID_DATA; + + if (ndrPtr) { - WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); - return SCARD_F_INTERNAL_ERROR; + // TODO: call->cbAttrLen was larger than the pointer value. + // TODO: Maybe need to refine the checks? + status = smartcard_ndr_read(s, &call->pbAttr, 0, 1, NDR_PTR_SIMPLE); + if (status != SCARD_S_SUCCESS) + return status; } - - Stream_Write_UINT32(s, ret->cbAttrLen); /* cbOutBufferSize (4 bytes) */ - Stream_Write(s, ret->pbAttr, ret->cbAttrLen); - - if ((error = smartcard_pack_write_size_align(smartcard, s, ret->cbAttrLen, 4))) - { - WLog_ERR(TAG, "smartcard_pack_write_size_align failed with error %" PRId32 "", error); - return error; - } - + smartcard_trace_set_attrib_call(smartcard, call); return SCARD_S_SUCCESS; } LONG smartcard_unpack_locate_cards_by_atr_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, LocateCardsByATRW_Call* call) { - UINT32 index; - UINT32 count; LONG status; - UINT32 offset; - UINT32 maxCount; - UINT32 szReaderNdrPtr; UINT32 rgReaderStatesNdrPtr; UINT32 rgAtrMasksNdrPtr; - + UINT32 index = 0; call->rgReaderStates = NULL; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext)); - if (status) + status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext), &index); + if (status != SCARD_S_SUCCESS) return status; if (Stream_GetRemainingLength(s) < 16) @@ -3607,23 +3338,15 @@ LONG smartcard_unpack_locate_cards_by_atr_w_call(SMARTCARD_DEVICE* smartcard, wS } Stream_Read_UINT32(s, call->cAtrs); - Stream_Read_UINT32(s, rgAtrMasksNdrPtr); + if (!smartcard_ndr_pointer_read(s, &index, &rgAtrMasksNdrPtr)) + return ERROR_INVALID_DATA; + Stream_Read_UINT32(s, call->cReaders); /* cReaders (4 bytes) */ - Stream_Read_UINT32(s, rgReaderStatesNdrPtr); /* rgReaderStatesNdrPtr (4 bytes) */ + if (!smartcard_ndr_pointer_read(s, &index, &rgReaderStatesNdrPtr)) + return ERROR_INVALID_DATA; if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->hContext)))) - { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %" PRId32 "", - status); return status; - } - - if (Stream_GetRemainingLength(s) < 4) - { - WLog_WARN(TAG, "LocateCardsByATRW_Call is too short: %" PRIuz "", - Stream_GetRemainingLength(s)); - return STATUS_BUFFER_TOO_SMALL; - } if ((rgAtrMasksNdrPtr && !call->cAtrs) || (!rgAtrMasksNdrPtr && call->cAtrs)) { @@ -3636,124 +3359,16 @@ LONG smartcard_unpack_locate_cards_by_atr_w_call(SMARTCARD_DEVICE* smartcard, wS if (rgAtrMasksNdrPtr) { - Stream_Read_UINT32(s, count); - - if (count != call->cAtrs) - { - WLog_WARN(TAG, - "LocateCardsByATRW_Call NdrCount (0x%08" PRIX32 ") and cAtrs (0x%08" PRIX32 - ") inconsistency", - count, call->cAtrs); - return STATUS_INVALID_PARAMETER; - } - - if (Stream_GetRemainingLength(s) < call->cAtrs) - { - WLog_WARN(TAG, - "LocateCardsByATRW_Call is too short: Actual: %" PRIuz ", Expected: %" PRIu32 - "", - Stream_GetRemainingLength(s), call->cAtrs); - return STATUS_BUFFER_TOO_SMALL; - } - - call->rgAtrMasks = (LocateCards_ATRMask*)calloc(call->cAtrs, sizeof(LocateCards_ATRMask)); - - if (!call->rgAtrMasks) - { - WLog_WARN(TAG, "LocateCardsByATRW_Call out of memory error (call->rgAtrMasks)"); - return STATUS_NO_MEMORY; - } - - for (index = 0; index < call->cAtrs; index++) - { - Stream_Read_UINT32(s, call->rgAtrMasks[index].cbAtr); - Stream_Read(s, call->rgAtrMasks[index].rgbAtr, 36); - Stream_Read(s, call->rgAtrMasks[index].rgbMask, 36); - } + status = smartcard_ndr_read_atrmask(s, &call->rgAtrMasks, call->cAtrs, NDR_PTR_SIMPLE); + if (status != SCARD_S_SUCCESS) + return status; } - Stream_Read_UINT32(s, count); - - if (count != call->cReaders) + if (rgReaderStatesNdrPtr) { - WLog_WARN(TAG, - "LocateCardsByATRW_Call unexpected reader count: Actual: %" PRIu32 - ", Expected: %" PRIu32 "", - count, call->cReaders); - return STATUS_INVALID_PARAMETER; - } - - if (call->cReaders > 0) - { - call->rgReaderStates = - (SCARD_READERSTATEW*)calloc(call->cReaders, sizeof(SCARD_READERSTATEW)); - - if (!call->rgReaderStates) - { - WLog_WARN(TAG, "LocateCardsByATRW_Call out of memory error (call->rgReaderStates)"); - return STATUS_NO_MEMORY; - } - - for (index = 0; index < call->cReaders; index++) - { - LPSCARD_READERSTATEW readerState = (LPSCARD_READERSTATEW)&call->rgReaderStates[index]; - - if (Stream_GetRemainingLength(s) < 52) - { - WLog_WARN(TAG, "LocateCardsByATRW_Call is too short: %" PRIuz "", - Stream_GetRemainingLength(s)); - return STATUS_BUFFER_TOO_SMALL; - } - - Stream_Read_UINT32(s, szReaderNdrPtr); /* szReaderNdrPtr (4 bytes) */ - Stream_Read_UINT32(s, readerState->dwCurrentState); /* dwCurrentState (4 bytes) */ - Stream_Read_UINT32(s, readerState->dwEventState); /* dwEventState (4 bytes) */ - Stream_Read_UINT32(s, readerState->cbAtr); /* cbAtr (4 bytes) */ - Stream_Read(s, readerState->rgbAtr, 32); /* rgbAtr [0..32] (32 bytes) */ - Stream_Seek(s, 4); /* rgbAtr [32..36] (4 bytes) */ - } - - for (index = 0; index < call->cReaders; index++) - { - LPSCARD_READERSTATEW readerState = (LPSCARD_READERSTATEW)&call->rgReaderStates[index]; - - if (Stream_GetRemainingLength(s) < 12) - { - WLog_WARN(TAG, "LocateCardsByATRW_Call is too short: %" PRIuz "", - Stream_GetRemainingLength(s)); - return STATUS_BUFFER_TOO_SMALL; - } - - Stream_Read_UINT32(s, maxCount); /* NdrMaxCount (4 bytes) */ - Stream_Read_UINT32(s, offset); /* NdrOffset (4 bytes) */ - Stream_Read_UINT32(s, count); /* NdrActualCount (4 bytes) */ - - if (Stream_GetRemainingLength(s) < count) - { - WLog_WARN(TAG, "LocateCardsByATRW_Call is too short: %" PRIuz "", - Stream_GetRemainingLength(s)); - return STATUS_BUFFER_TOO_SMALL; - } - - readerState->szReader = (LPWSTR)calloc(count + 1, sizeof(WCHAR)); - - if (!readerState->szReader) - { - WLog_WARN(TAG, - "LocateCardsByATRW_Call out of memory error (readerState->szReader)"); - return STATUS_NO_MEMORY; - } - - Stream_Read_UTF16_String(s, readerState->szReader, count); - - smartcard_unpack_read_size_align(smartcard, s, count, 4); - - if (!readerState->szReader) - { - WLog_WARN(TAG, "LocateCardsByATRW_Call null reader name"); - return STATUS_INVALID_PARAMETER; - } - } + status = smartcard_unpack_reader_state_w(s, &call->rgReaderStates, call->cReaders, &index); + if (status != SCARD_S_SUCCESS) + return status; } smartcard_trace_locate_cards_by_atr_w_call(smartcard, call); @@ -3766,19 +3381,20 @@ LONG smartcard_unpack_read_cache_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, LONG status; UINT32 mszNdrPtr; UINT32 contextNdrPtr; - smartcard_trace_read_cache_a_call(smartcard, call); + UINT32 index = 0; - if (Stream_GetRemainingLength(s) < 4) - return STATUS_BUFFER_TOO_SMALL; - Stream_Read_UINT32(s, mszNdrPtr); + if (!smartcard_ndr_pointer_read(s, &index, &mszNdrPtr)) + return ERROR_INVALID_DATA; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->Common.hContext)); - if (status) + status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->Common.hContext), &index); + if (status != SCARD_S_SUCCESS) return status; - if (Stream_GetRemainingLength(s) < 16) + if (!smartcard_ndr_pointer_read(s, &index, &contextNdrPtr)) + return ERROR_INVALID_DATA; + + if (Stream_GetRemainingLength(s) < 12) return STATUS_BUFFER_TOO_SMALL; - Stream_Read_UINT32(s, contextNdrPtr); Stream_Read_UINT32(s, call->Common.FreshnessCounter); Stream_Read_INT32(s, call->Common.fPbDataIsNULL); Stream_Read_UINT32(s, call->Common.cbDataLen); @@ -3786,17 +3402,22 @@ LONG smartcard_unpack_read_cache_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, call->szLookupName = NULL; if (mszNdrPtr) { - status = smartcard_ndr_read_a(s, &call->szLookupName, sizeof(CHAR)); - if (status) + status = smartcard_ndr_read_a(s, &call->szLookupName, NDR_PTR_FULL); + if (status != SCARD_S_SUCCESS) return status; } + status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &call->Common.hContext); + if (status != SCARD_S_SUCCESS) + return status; + if (contextNdrPtr) { - status = smartcard_ndr_read_u(s, &call->Common.CardIdentifier, sizeof(UUID)); - if (status) + status = smartcard_ndr_read_u(s, &call->Common.CardIdentifier); + if (status != SCARD_S_SUCCESS) return status; } + smartcard_trace_read_cache_a_call(smartcard, call); return SCARD_S_SUCCESS; } @@ -3806,19 +3427,20 @@ LONG smartcard_unpack_read_cache_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, LONG status; UINT32 mszNdrPtr; UINT32 contextNdrPtr; - smartcard_trace_read_cache_w_call(smartcard, call); + UINT32 index = 0; - if (Stream_GetRemainingLength(s) < 4) - return STATUS_BUFFER_TOO_SMALL; - Stream_Read_UINT32(s, mszNdrPtr); + if (!smartcard_ndr_pointer_read(s, &index, &mszNdrPtr)) + return ERROR_INVALID_DATA; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->Common.hContext)); - if (status) + status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->Common.hContext), &index); + if (status != SCARD_S_SUCCESS) return status; - if (Stream_GetRemainingLength(s) < 16) + if (!smartcard_ndr_pointer_read(s, &index, &contextNdrPtr)) + return ERROR_INVALID_DATA; + + if (Stream_GetRemainingLength(s) < 12) return STATUS_BUFFER_TOO_SMALL; - Stream_Read_UINT32(s, contextNdrPtr); Stream_Read_UINT32(s, call->Common.FreshnessCounter); Stream_Read_INT32(s, call->Common.fPbDataIsNULL); Stream_Read_UINT32(s, call->Common.cbDataLen); @@ -3826,17 +3448,22 @@ LONG smartcard_unpack_read_cache_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, call->szLookupName = NULL; if (mszNdrPtr) { - status = smartcard_ndr_read_w(s, &call->szLookupName, sizeof(WCHAR)); - if (status) + status = smartcard_ndr_read_w(s, &call->szLookupName, NDR_PTR_FULL); + if (status != SCARD_S_SUCCESS) return status; } + status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &call->Common.hContext); + if (status != SCARD_S_SUCCESS) + return status; + if (contextNdrPtr) { - status = smartcard_ndr_read(s, &call->Common.CardIdentifier, sizeof(UUID)); - if (status) + status = smartcard_ndr_read_u(s, &call->Common.CardIdentifier); + if (status != SCARD_S_SUCCESS) return status; } + smartcard_trace_read_cache_w_call(smartcard, call); return SCARD_S_SUCCESS; } @@ -3847,46 +3474,56 @@ LONG smartcard_unpack_write_cache_a_call(SMARTCARD_DEVICE* smartcard, wStream* s UINT32 mszNdrPtr; UINT32 contextNdrPtr; UINT32 pbDataNdrPtr; - smartcard_trace_write_cache_a_call(smartcard, call); + UINT32 index = 0; - if (Stream_GetRemainingLength(s) < 4) - return STATUS_BUFFER_TOO_SMALL; - Stream_Read_UINT32(s, mszNdrPtr); + if (!smartcard_ndr_pointer_read(s, &index, &mszNdrPtr)) + return ERROR_INVALID_DATA; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->Common.hContext)); - if (status) + status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->Common.hContext), &index); + if (status != SCARD_S_SUCCESS) return status; - if (Stream_GetRemainingLength(s) < 16) + if (!smartcard_ndr_pointer_read(s, &index, &contextNdrPtr)) + return ERROR_INVALID_DATA; + + if (Stream_GetRemainingLength(s) < 8) return STATUS_BUFFER_TOO_SMALL; - Stream_Read_UINT32(s, contextNdrPtr); + Stream_Read_UINT32(s, call->Common.FreshnessCounter); Stream_Read_UINT32(s, call->Common.cbDataLen); - Stream_Read_UINT32(s, pbDataNdrPtr); + + if (!smartcard_ndr_pointer_read(s, &index, &pbDataNdrPtr)) + return ERROR_INVALID_DATA; call->szLookupName = NULL; if (mszNdrPtr) { - status = smartcard_ndr_read_a(s, &call->szLookupName, sizeof(CHAR)); - if (status) + status = smartcard_ndr_read_a(s, &call->szLookupName, NDR_PTR_FULL); + if (status != SCARD_S_SUCCESS) return status; } + status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &call->Common.hContext); + if (status != SCARD_S_SUCCESS) + return status; + call->Common.CardIdentifier = NULL; if (contextNdrPtr) { - status = smartcard_ndr_read_u(s, &call->Common.CardIdentifier, sizeof(UUID)); - if (status) + status = smartcard_ndr_read_u(s, &call->Common.CardIdentifier); + if (status != SCARD_S_SUCCESS) return status; } call->Common.pbData = NULL; if (pbDataNdrPtr) { - status = smartcard_ndr_read(s, &call->Common.pbData, sizeof(CHAR)); - if (status) + status = + smartcard_ndr_read(s, &call->Common.pbData, call->Common.cbDataLen, 1, NDR_PTR_SIMPLE); + if (status != SCARD_S_SUCCESS) return status; } + smartcard_trace_write_cache_a_call(smartcard, call); return SCARD_S_SUCCESS; } @@ -3897,62 +3534,84 @@ LONG smartcard_unpack_write_cache_w_call(SMARTCARD_DEVICE* smartcard, wStream* s UINT32 mszNdrPtr; UINT32 contextNdrPtr; UINT32 pbDataNdrPtr; - smartcard_trace_write_cache_w_call(smartcard, call); + UINT32 index = 0; - if (Stream_GetRemainingLength(s) < 4) - return STATUS_BUFFER_TOO_SMALL; - Stream_Read_UINT32(s, mszNdrPtr); + if (!smartcard_ndr_pointer_read(s, &index, &mszNdrPtr)) + return ERROR_INVALID_DATA; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->Common.hContext)); - if (status) + status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->Common.hContext), &index); + if (status != SCARD_S_SUCCESS) return status; - if (Stream_GetRemainingLength(s) < 16) + if (!smartcard_ndr_pointer_read(s, &index, &contextNdrPtr)) + return ERROR_INVALID_DATA; + + if (Stream_GetRemainingLength(s) < 8) return STATUS_BUFFER_TOO_SMALL; - Stream_Read_UINT32(s, contextNdrPtr); Stream_Read_UINT32(s, call->Common.FreshnessCounter); Stream_Read_UINT32(s, call->Common.cbDataLen); - Stream_Read_UINT32(s, pbDataNdrPtr); + + if (!smartcard_ndr_pointer_read(s, &index, &pbDataNdrPtr)) + return ERROR_INVALID_DATA; call->szLookupName = NULL; if (mszNdrPtr) { - status = smartcard_ndr_read_w(s, &call->szLookupName, sizeof(WCHAR)); - if (status) + status = smartcard_ndr_read_w(s, &call->szLookupName, NDR_PTR_FULL); + if (status != SCARD_S_SUCCESS) return status; } + status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &call->Common.hContext); + if (status != SCARD_S_SUCCESS) + return status; + call->Common.CardIdentifier = NULL; if (contextNdrPtr) { - status = smartcard_ndr_read_u(s, &call->Common.CardIdentifier, sizeof(UUID)); - if (status) + status = smartcard_ndr_read_u(s, &call->Common.CardIdentifier); + if (status != SCARD_S_SUCCESS) return status; } call->Common.pbData = NULL; if (pbDataNdrPtr) { - status = smartcard_ndr_read(s, &call->Common.pbData, sizeof(CHAR)); - if (status) + status = + smartcard_ndr_read(s, &call->Common.pbData, call->Common.cbDataLen, 1, NDR_PTR_SIMPLE); + if (status != SCARD_S_SUCCESS) return status; } - return SCARD_S_SUCCESS; + smartcard_trace_write_cache_w_call(smartcard, call); + return status; } LONG smartcard_unpack_get_transmit_count_call(SMARTCARD_DEVICE* smartcard, wStream* s, GetTransmitCount_Call* call) { LONG status; + UINT32 index = 0; + + status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext), &index); + if (status != SCARD_S_SUCCESS) + return status; + + status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->hCard), &index); + if (status != SCARD_S_SUCCESS) + return status; + + if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->hContext)))) + { + WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %" PRId32 "", + status); + return status; + } + + if ((status = smartcard_unpack_redir_scard_handle_ref(smartcard, s, &(call->hCard)))) + WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle_ref failed with error %" PRId32 "", + status); + smartcard_trace_get_transmit_count_call(smartcard, call); - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext)); - if (status) - return status; - - status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->hCard)); - if (status) - return status; - return status; } @@ -3985,10 +3644,11 @@ LONG smartcard_unpack_get_device_type_id_call(SMARTCARD_DEVICE* smartcard, wStre LONG smartcard_pack_device_type_id_return(SMARTCARD_DEVICE* smartcard, wStream* s, const GetDeviceTypeId_Return* ret) { - WINPR_UNUSED(smartcard); smartcard_trace_device_type_id_return(smartcard, ret); + if (ret->ReturnCode != SCARD_S_SUCCESS) + return ret->ReturnCode; - if (!Stream_EnsureRemainingCapacity(s, 8)) + if (!Stream_EnsureRemainingCapacity(s, 4)) { WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); return SCARD_F_INTERNAL_ERROR; @@ -4002,78 +3662,53 @@ LONG smartcard_pack_device_type_id_return(SMARTCARD_DEVICE* smartcard, wStream* LONG smartcard_pack_locate_cards_return(SMARTCARD_DEVICE* smartcard, wStream* s, const LocateCards_Return* ret) { - - UINT32 pbDataNdrPtr = (ret->rgReaderStates) ? 0x00020000 : 0; + DWORD index = 0; smartcard_trace_locate_cards_return(smartcard, ret); - if (!Stream_EnsureRemainingCapacity(s, 8)) + if (ret->ReturnCode != SCARD_S_SUCCESS) + return ret->ReturnCode; + + if (!Stream_EnsureRemainingCapacity(s, 4)) { WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); return SCARD_F_INTERNAL_ERROR; } Stream_Write_UINT32(s, ret->cReaders); /* cBytes (4 cbDataLen) */ - Stream_Write_UINT32(s, pbDataNdrPtr); - if (ret->rgReaderStates) - { - size_t x, size; + if (!smartcard_ndr_pointer_write(s, &index, ret->cReaders)) + return SCARD_E_NO_MEMORY; - size = sizeof(ReaderState_Return) * ret->cReaders; - if (!Stream_EnsureRemainingCapacity(s, size + 8)) - { - WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); - return SCARD_F_INTERNAL_ERROR; - } - - Stream_Write_UINT32(s, (UINT32)size); - for (x = 0; x < ret->cReaders; x++) - { - ReaderState_Return* reader = &ret->rgReaderStates[x]; - Stream_Write_UINT32(s, reader->dwCurrentState); - Stream_Write_UINT32(s, reader->dwEventState); - Stream_Write_UINT32(s, reader->cbAtr); - Stream_Write(s, reader->rgbAtr, sizeof(reader->rgbAtr)); - } - smartcard_pack_write_size_align(smartcard, s, (UINT32)size, 4); - } - - return SCARD_S_SUCCESS; + return smartcard_ndr_write_state(s, ret->rgReaderStates, ret->cReaders, NDR_PTR_SIMPLE); } LONG smartcard_pack_get_reader_icon_return(SMARTCARD_DEVICE* smartcard, wStream* s, const GetReaderIcon_Return* ret) { - UINT32 pbDataNdrPtr = (ret->pbData) ? 0x00020000 : 0; + DWORD index = 0; smartcard_trace_get_reader_icon_return(smartcard, ret); - if (!Stream_EnsureRemainingCapacity(s, 8)) + if (ret->ReturnCode != SCARD_S_SUCCESS) + return ret->ReturnCode; + + if (!Stream_EnsureRemainingCapacity(s, 4)) { WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); return SCARD_F_INTERNAL_ERROR; } Stream_Write_UINT32(s, ret->cbDataLen); /* cBytes (4 cbDataLen) */ - Stream_Write_UINT32(s, pbDataNdrPtr); - if (ret->pbData) - { - if (!Stream_EnsureRemainingCapacity(s, ret->cbDataLen + 8)) - { - WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); - return SCARD_F_INTERNAL_ERROR; - } + if (!smartcard_ndr_pointer_write(s, &index, ret->cbDataLen)) + return SCARD_E_NO_MEMORY; - Stream_Write_UINT32(s, ret->cbDataLen); - Stream_Write(s, ret->pbData, ret->cbDataLen); - smartcard_pack_write_size_align(smartcard, s, ret->cbDataLen, 4); - } - - return SCARD_S_SUCCESS; + return smartcard_ndr_write(s, ret->pbData, ret->cbDataLen, 1, NDR_PTR_SIMPLE); } LONG smartcard_pack_get_transmit_count_return(SMARTCARD_DEVICE* smartcard, wStream* s, const GetTransmitCount_Return* ret) { - smartcard_trace_get_transmit_count_return(smartcard, ret); - if (!Stream_EnsureRemainingCapacity(s, 8)) + if (ret->ReturnCode != SCARD_S_SUCCESS) + return ret->ReturnCode; + + if (!Stream_EnsureRemainingCapacity(s, 4)) { WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); return SCARD_F_INTERNAL_ERROR; @@ -4087,28 +3722,21 @@ LONG smartcard_pack_get_transmit_count_return(SMARTCARD_DEVICE* smartcard, wStre LONG smartcard_pack_read_cache_return(SMARTCARD_DEVICE* smartcard, wStream* s, const ReadCache_Return* ret) { - UINT32 pbDataNdrPtr = (ret->pbData) ? 0x00020000 : 0; + DWORD index = 0; + smartcard_trace_read_cache_return(smartcard, ret); - if (!Stream_EnsureRemainingCapacity(s, 8)) + if (ret->ReturnCode != SCARD_S_SUCCESS) + return ret->ReturnCode; + + if (!Stream_EnsureRemainingCapacity(s, 4)) { WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); return SCARD_F_INTERNAL_ERROR; } Stream_Write_UINT32(s, ret->cbDataLen); /* cBytes (4 cbDataLen) */ - Stream_Write_UINT32(s, pbDataNdrPtr); - if (ret->pbData) - { - if (!Stream_EnsureRemainingCapacity(s, ret->cbDataLen + 8)) - { - WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); - return SCARD_F_INTERNAL_ERROR; - } + if (!smartcard_ndr_pointer_write(s, &index, ret->cbDataLen)) + return SCARD_E_NO_MEMORY; - Stream_Write_UINT32(s, ret->cbDataLen); - Stream_Write(s, ret->pbData, ret->cbDataLen); - smartcard_pack_write_size_align(smartcard, s, ret->cbDataLen, 4); - } - - return SCARD_S_SUCCESS; + return smartcard_ndr_write(s, ret->pbData, ret->cbDataLen, 1, NDR_PTR_SIMPLE); } diff --git a/channels/smartcard/client/smartcard_pack.h b/channels/smartcard/client/smartcard_pack.h index d0d830231..85cb91efc 100644 --- a/channels/smartcard/client/smartcard_pack.h +++ b/channels/smartcard/client/smartcard_pack.h @@ -5,6 +5,8 @@ * Copyright 2014 Marc-Andre Moreau * Copyright 2015 Thincast Technologies GmbH * Copyright 2015 DI (FH) Martin Haimberger + * Copyright 2020 Armin Novak + * Copyright 2020 Thincast Technologies GmbH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,6 +28,8 @@ #include #include +#pragma pack(push, 1) + /* interface type_scard_pack */ /* [unique][version][uuid] */ @@ -138,7 +142,7 @@ typedef struct _LocateCardsA_Call { REDIR_SCARDCONTEXT hContext; /* [range] */ DWORD cBytes; - /* [size_is] */ char* mszCards; + /* [size_is] */ CHAR* mszCards; /* [range] */ DWORD cReaders; /* [size_is] */ LPSCARD_READERSTATEA rgReaderStates; } LocateCardsA_Call; @@ -228,7 +232,7 @@ typedef struct _Connect_Common typedef struct _ConnectA_Call { - /* [string] */ unsigned char* szReader; + /* [string] */ CHAR* szReader; Connect_Common Common; } ConnectA_Call; @@ -436,14 +440,16 @@ typedef struct _WriteCacheW_Call WriteCache_Common Common; } WriteCacheW_Call; +#pragma pack(pop) + #define SMARTCARD_COMMON_TYPE_HEADER_LENGTH 8 #define SMARTCARD_PRIVATE_TYPE_HEADER_LENGTH 8 #include "smartcard_main.h" -LONG smartcard_pack_write_size_align(SMARTCARD_DEVICE* smartcard, wStream* s, UINT32 size, +LONG smartcard_pack_write_size_align(SMARTCARD_DEVICE* smartcard, wStream* s, size_t size, UINT32 alignment); -LONG smartcard_unpack_read_size_align(SMARTCARD_DEVICE* smartcard, wStream* s, UINT32 size, +LONG smartcard_unpack_read_size_align(SMARTCARD_DEVICE* smartcard, wStream* s, size_t size, UINT32 alignment); SCARDCONTEXT smartcard_scard_context_native_from_redir(SMARTCARD_DEVICE* smartcard, @@ -479,7 +485,7 @@ LONG smartcard_unpack_list_reader_groups_call(SMARTCARD_DEVICE* smartcard, wStre ListReaderGroups_Call* call, BOOL unicode); LONG smartcard_pack_list_reader_groups_return(SMARTCARD_DEVICE* smartcard, wStream* s, - const ListReaderGroups_Return* ret); + const ListReaderGroups_Return* ret, BOOL unicode); LONG smartcard_unpack_list_readers_call(SMARTCARD_DEVICE* smartcard, wStream* s, ListReaders_Call* call, BOOL unicode); @@ -515,8 +521,8 @@ LONG smartcard_unpack_connect_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, Co LONG smartcard_unpack_connect_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, ConnectW_Call* call); -LONG smartcard_pack_connect_return(SMARTCARD_DEVICE* smartcard, wStream* s, Connect_Return* ret); -void smartcard_trace_connect_return(SMARTCARD_DEVICE* smartcard, const Connect_Return* ret); +LONG smartcard_pack_connect_return(SMARTCARD_DEVICE* smartcard, wStream* s, + const Connect_Return* ret); LONG smartcard_unpack_reconnect_call(SMARTCARD_DEVICE* smartcard, wStream* s, Reconnect_Call* call); @@ -553,9 +559,6 @@ LONG smartcard_pack_get_attrib_return(SMARTCARD_DEVICE* smartcard, wStream* s, LONG smartcard_unpack_set_attrib_call(SMARTCARD_DEVICE* smartcard, wStream* s, SetAttrib_Call* call); -LONG smartcard_pack_set_attrib_return(SMARTCARD_DEVICE* smartcard, wStream* s, - const GetAttrib_Return* ret); - LONG smartcard_unpack_control_call(SMARTCARD_DEVICE* smartcard, wStream* s, Control_Call* call); LONG smartcard_pack_control_return(SMARTCARD_DEVICE* smartcard, wStream* s, diff --git a/scripts/test-scard.cpp b/scripts/test-scard.cpp new file mode 100644 index 000000000..d22fca900 --- /dev/null +++ b/scripts/test-scard.cpp @@ -0,0 +1,921 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Smartcard API test program + * + * This simple program can be used to trigger calls for (almost) the + * entire SCARD API. + * Compile on windows, connect with FreeRDP via RDP with smartcard + * redirection enabled and run this test program on the windows + * machine. + * + * Copyright 2020 Armin Novak + * Copyright 2020 Thincast Technologies GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#include +#include + +static const WCHAR* listW[] = { nullptr, L"SCard$AllReaders\000", L"SCard$DefaultReaders\000", + L"SCard$LocalReaders\000", L"SCard$SystemReaders\000" }; +static const char* listA[] = { nullptr, "SCard$AllReaders\000", "SCard$DefaultReaders\000", + "SCard$LocalReaders\000", "SCard$SystemReaders\000" }; + +static std::string scope2str(DWORD scope) +{ + switch (scope) + { + case SCARD_SCOPE_USER: + return "SCARD_SCOPE_USER"; + case SCARD_SCOPE_TERMINAL: + return "SCARD_SCOPE_TERMINAL"; + case SCARD_SCOPE_SYSTEM: + return "SCARD_SCOPE_SYSTEM"; + default: + return "UNKNOWN"; + } +} + +static std::string err2str(LONG code) +{ + switch (code) + { + case ERROR_BROKEN_PIPE: + return "ERROR_BROKEN_PIPE"; + case SCARD_E_BAD_SEEK: + return "SCARD_E_BAD_SEEK"; + case SCARD_E_CANCELLED: + return "SCARD_E_CANCELLED"; + case SCARD_E_CANT_DISPOSE: + return "SCARD_E_CANT_DISPOSE"; + case SCARD_E_CARD_UNSUPPORTED: + return "SCARD_E_CARD_UNSUPPORTED"; + case SCARD_E_CERTIFICATE_UNAVAILABLE: + return "SCARD_E_CERTIFICATE_UNAVAILABLE"; + case SCARD_E_COMM_DATA_LOST: + return "SCARD_E_COMM_DATA_LOST"; + case SCARD_E_DIR_NOT_FOUND: + return "SCARD_E_DIR_NOT_FOUND"; + case SCARD_E_DUPLICATE_READER: + return "SCARD_E_DUPLICATE_READER"; + case SCARD_E_FILE_NOT_FOUND: + return "SCARD_E_FILE_NOT_FOUND"; + case SCARD_E_ICC_CREATEORDER: + return "SCARD_E_ICC_CREATEORDER"; + case SCARD_E_ICC_INSTALLATION: + return "SCARD_E_ICC_INSTALLATION"; + case SCARD_E_INSUFFICIENT_BUFFER: + return "SCARD_E_INSUFFICIENT_BUFFER"; + case SCARD_E_INVALID_ATR: + return "SCARD_E_INVALID_ATR"; + case SCARD_E_INVALID_CHV: + return "SCARD_E_INVALID_CHV"; + case SCARD_E_INVALID_HANDLE: + return "SCARD_E_INVALID_HANDLE"; + case SCARD_E_INVALID_PARAMETER: + return "SCARD_E_INVALID_PARAMETER"; + case SCARD_E_INVALID_TARGET: + return "SCARD_E_INVALID_TARGET"; + case SCARD_E_INVALID_VALUE: + return "SCARD_E_INVALID_VALUE"; + case SCARD_E_NO_ACCESS: + return "SCARD_E_NO_ACCESS"; + case SCARD_E_NO_DIR: + return "SCARD_E_NO_DIR"; + case SCARD_E_NO_FILE: + return "SCARD_E_NO_FILE"; + case SCARD_E_NO_KEY_CONTAINER: + return "SCARD_E_NO_KEY_CONTAINER"; + case SCARD_E_NO_MEMORY: + return "SCARD_E_NO_MEMORY"; + case SCARD_E_NO_PIN_CACHE: + return "SCARD_E_NO_PIN_CACHE"; + case SCARD_E_NO_READERS_AVAILABLE: + return "SCARD_E_NO_READERS_AVAILABLE"; + case SCARD_E_NO_SERVICE: + return "SCARD_E_NO_SERVICE"; + case SCARD_E_NO_SMARTCARD: + return "SCARD_E_NO_SMARTCARD"; + case SCARD_E_NO_SUCH_CERTIFICATE: + return "SCARD_E_NO_SUCH_CERTIFICATE"; + case SCARD_E_NOT_READY: + return "SCARD_E_NOT_READY"; + case SCARD_E_NOT_TRANSACTED: + return "SCARD_E_NOT_TRANSACTED"; + case SCARD_E_PCI_TOO_SMALL: + return "SCARD_E_PCI_TOO_SMALL"; + case SCARD_E_PIN_CACHE_EXPIRED: + return "SCARD_E_PIN_CACHE_EXPIRED"; + case SCARD_E_PROTO_MISMATCH: + return "SCARD_E_PROTO_MISMATCH"; + case SCARD_E_READ_ONLY_CARD: + return "SCARD_E_READ_ONLY_CARD"; + case SCARD_E_READER_UNAVAILABLE: + return "SCARD_E_READER_UNAVAILABLE"; + case SCARD_E_READER_UNSUPPORTED: + return "SCARD_E_READER_UNSUPPORTED"; + case SCARD_E_SERVER_TOO_BUSY: + return "SCARD_E_SERVER_TOO_BUSY"; + case SCARD_E_SERVICE_STOPPED: + return "SCARD_E_SERVICE_STOPPED"; + case SCARD_E_SHARING_VIOLATION: + return "SCARD_E_SHARING_VIOLATION"; + case SCARD_E_SYSTEM_CANCELLED: + return "SCARD_E_SYSTEM_CANCELLED"; + case SCARD_E_TIMEOUT: + return "SCARD_E_TIMEOUT"; + case SCARD_E_UNEXPECTED: + return "SCARD_E_UNEXPECTED"; + case SCARD_E_UNKNOWN_CARD: + return "SCARD_E_UNKNOWN_CARD"; + case SCARD_E_UNKNOWN_READER: + return "SCARD_E_UNKNOWN_READER"; + case SCARD_E_UNKNOWN_RES_MNG: + return "SCARD_E_UNKNOWN_RES_MNG"; + case SCARD_E_UNSUPPORTED_FEATURE: + return "SCARD_E_UNSUPPORTED_FEATURE"; + case SCARD_E_WRITE_TOO_MANY: + return "SCARD_E_WRITE_TOO_MANY"; + case SCARD_F_COMM_ERROR: + return "SCARD_F_COMM_ERROR"; + case SCARD_F_INTERNAL_ERROR: + return "SCARD_F_INTERNAL_ERROR"; + case SCARD_F_UNKNOWN_ERROR: + return "SCARD_F_UNKNOWN_ERROR"; + case SCARD_F_WAITED_TOO_LONG: + return "SCARD_F_WAITED_TOO_LONG"; + case SCARD_P_SHUTDOWN: + return "SCARD_P_SHUTDOWN"; + case SCARD_S_SUCCESS: + return "SCARD_S_SUCCESS"; + case SCARD_W_CANCELLED_BY_USER: + return "SCARD_W_CANCELLED_BY_USER"; + case SCARD_W_CACHE_ITEM_NOT_FOUND: + return "SCARD_W_CACHE_ITEM_NOT_FOUND"; + case SCARD_W_CACHE_ITEM_STALE: + return "SCARD_W_CACHE_ITEM_STALE"; + case SCARD_W_CACHE_ITEM_TOO_BIG: + return "SCARD_W_CACHE_ITEM_TOO_BIG"; + case SCARD_W_CARD_NOT_AUTHENTICATED: + return "SCARD_W_CARD_NOT_AUTHENTICATED"; + case SCARD_W_CHV_BLOCKED: + return "SCARD_W_CHV_BLOCKED"; + case SCARD_W_EOF: + return "SCARD_W_EOF"; + case SCARD_W_REMOVED_CARD: + return "SCARD_W_REMOVED_CARD"; + case SCARD_W_RESET_CARD: + return "SCARD_W_RESET_CARD"; + case SCARD_W_SECURITY_VIOLATION: + return "SCARD_W_SECURITY_VIOLATION"; + case SCARD_W_UNPOWERED_CARD: + return "SCARD_W_UNPOWERED_CARD"; + case SCARD_W_UNRESPONSIVE_CARD: + return "SCARD_W_UNRESPONSIVE_CARD"; + case SCARD_W_UNSUPPORTED_CARD: + return "SCARD_W_UNSUPPORTED_CARD"; + case SCARD_W_WRONG_CHV: + return "SCARD_W_WRONG_CHV"; + default: + return "UNKNOWN"; + } +} + +static std::wstring err2wstr(LONG code) +{ + auto str = err2str(code); + std::wstring_convert> converter; + return converter.from_bytes(str); +} + +#if 0 +static bool test_listreadergroups(SCARDCONTEXT hContext) { + auto rc = SCardListReaderGroupsA(hContext, &groups, &foobar); + rc = SCardListReaderGroupsW(hContext, &groups, &foobar); +} +#endif + +static bool test_valid(SCARDCONTEXT context) +{ + auto rc = SCardIsValidContext(context); + if (rc) + std::cerr << "SCardIsValidContext failed with " << err2str(rc) << std::endl; + return true; +} + +static bool test_list_readers_a(SCARDCONTEXT context) +{ + for (auto cur : listA) + { + LPSTR mszReaders = nullptr; + DWORD chReaders = SCARD_AUTOALLOCATE; + auto rc = SCardListReadersA(context, cur, reinterpret_cast(&mszReaders), &chReaders); + if (!cur) + { + cur = "NULL"; + } + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardListReadersA [" << cur << "] failed with " << err2str(rc) + << std::endl; + } + else + { + auto start = mszReaders; + auto end = &mszReaders[chReaders]; + + std::cout << "SCardListReadersA [" << cur << "] " << chReaders << " ["; + while (start < end) + { + std::cout << start << ", "; + start += strnlen(start, chReaders) + 2; + } + std::cout << "]" << std::endl; + } + SCardFreeMemory(context, mszReaders); + } + + return true; +} + +static bool test_list_readers_w(SCARDCONTEXT context) +{ + for (auto cur : listW) + { + LPWSTR mszReaders = nullptr; + DWORD chReaders = SCARD_AUTOALLOCATE; + auto rc = + SCardListReadersW(context, cur, reinterpret_cast(&mszReaders), &chReaders); + if (!cur) + { + cur = L"NULL"; + } + if (rc != SCARD_S_SUCCESS) + { + std::wcerr << L"SCardListReadersW [" << cur << L"] failed with " << err2wstr(rc) + << std::endl; + } + else + { + auto start = mszReaders; + auto end = &mszReaders[chReaders]; + + std::wcout << L"SCardListReadersW [" << cur << L"] " << chReaders << L" ["; + while (start < end) + { + std::wcout << start << L", "; + start += wcsnlen(start, chReaders) + 2; + } + std::wcout << L"]" << std::endl; + } + SCardFreeMemory(context, mszReaders); + } + + return true; +} + +static bool test_list_reader_groups_a(SCARDCONTEXT context) +{ + LPSTR mszReaders = nullptr; + DWORD chReaders = SCARD_AUTOALLOCATE; + auto rc = SCardListReaderGroupsA(context, reinterpret_cast(&mszReaders), &chReaders); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardListReaderGroupsA failed with " << err2str(rc) << std::endl; + } + else + { + auto start = mszReaders; + auto end = &mszReaders[chReaders]; + + std::cout << "SCardListReaderGroupsA " << chReaders << " ["; + while (start < end) + { + std::cout << start << ", "; + start += strnlen(start, chReaders) + 2; + } + std::cout << "]" << std::endl; + } + SCardFreeMemory(context, mszReaders); + + return true; +} + +static bool test_list_reader_groups_w(SCARDCONTEXT context) +{ + LPWSTR mszReaders = nullptr; + DWORD chReaders = SCARD_AUTOALLOCATE; + auto rc = SCardListReaderGroupsW(context, reinterpret_cast(&mszReaders), &chReaders); + if (rc != SCARD_S_SUCCESS) + { + std::wcerr << L"SCardListReaderGroupsW failed with " << err2wstr(rc) << std::endl; + } + else + { + auto start = mszReaders; + auto end = &mszReaders[chReaders]; + + std::wcout << L"SCardListReaderGroupsW " << chReaders << L" ["; + while (start < end) + { + std::wcout << start << L", "; + start += wcsnlen(start, chReaders) + 2; + } + std::wcout << L"]" << std::endl; + } + SCardFreeMemory(context, mszReaders); + + return true; +} + +static bool test_introduce_forget_reader_groups_a(SCARDCONTEXT context) +{ + LPSTR group = "somefancygroup"; + + auto rc = SCardIntroduceReaderGroupA(context, group); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardIntroduceReaderGroupA failed with " << err2str(rc) << std::endl; + return false; + } + else + { + rc = SCardForgetReaderGroupA(context, group); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardForgetReaderGroupA failed with " << err2str(rc) << std::endl; + return false; + } + return true; + } +} + +static bool test_introduce_forget_reader_groups_w(SCARDCONTEXT context) +{ + LPWSTR group = L"somefancygroup"; + + auto rc = SCardIntroduceReaderGroupW(context, group); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardIntroduceReaderGroupW failed with " << err2str(rc) << std::endl; + return false; + } + else + { + rc = SCardForgetReaderGroupW(context, group); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardForgetReaderGroupW failed with " << err2str(rc) << std::endl; + return false; + } + return true; + } +} + +static bool test_introduce_forget_reader_a(SCARDCONTEXT context) +{ + LPSTR reader = "somefancygroup"; + LPSTR device = "otherfancy"; + + auto rc = SCardIntroduceReaderA(context, reader, device); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardIntroduceReaderA failed with " << err2str(rc) << std::endl; + return false; + } + else + { + rc = SCardForgetReaderA(context, reader); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardForgetReaderA failed with " << err2str(rc) << std::endl; + return false; + } + return true; + } +} + +static bool test_introduce_forget_reader_w(SCARDCONTEXT context) +{ + LPWSTR reader = L"somefancygroup"; + LPWSTR device = L"otherfancy"; + + auto rc = SCardIntroduceReaderW(context, reader, device); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardIntroduceReaderW failed with " << err2str(rc) << std::endl; + return false; + } + else + { + rc = SCardForgetReaderW(context, reader); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardForgetReaderW failed with " << err2str(rc) << std::endl; + return false; + } + return true; + } +} + +static bool test_list_cards_a(SCARDCONTEXT context) +{ + DWORD chCards = SCARD_AUTOALLOCATE; + LPSTR mszCards = nullptr; + auto rc = + SCardListCardsA(context, nullptr, nullptr, 0, reinterpret_cast(&mszCards), &chCards); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardListCardsA failed with " << err2str(rc) << std::endl; + } + else + { + auto start = mszCards; + auto end = &mszCards[chCards]; + std::cout << "SCardListCardsA " << chCards << " ["; + while (start < end) + { + std::cout << start << ", "; + start += strnlen(start, chCards) + 2; + } + std::cout << "]" << std::endl; + } + return true; +} + +static bool test_list_cards_w(SCARDCONTEXT context) +{ + DWORD chCards = SCARD_AUTOALLOCATE; + LPWSTR mszCards = nullptr; + auto rc = SCardListCardsW(context, nullptr, nullptr, 0, reinterpret_cast(&mszCards), + &chCards); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardListCardsW failed with " << err2str(rc) << std::endl; + } + else + { + auto start = mszCards; + auto end = &mszCards[chCards]; + std::cout << "SCardListCardsW " << chCards << " ["; + while (start < end) + { + std::wcout << start << L", "; + start += wcsnlen(start, chCards) + 2; + } + std::cout << "]" << std::endl; + } + return true; +} + +static bool test_cache_a(SCARDCONTEXT context) +{ + BYTE wdata[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + const DWORD wdatalen = sizeof(wdata); + BYTE data[32] = {}; + DWORD datalen = sizeof(data); + LPSTR name = "testdata"; + UUID id = {}; + + auto rc = SCardWriteCacheA(context, &id, 0, name, wdata, wdatalen); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardWriteCacheA failed with " << err2str(rc) << std::endl; + return false; + } + + rc = SCardReadCacheA(context, &id, 0, name, data, &datalen); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardReadCacheA failed with " << err2str(rc) << std::endl; + return false; + } + + if (wdatalen != datalen) + { + std::cerr << "SCardWriteCacheA wrote " << wdatalen << "bytes, SCardReadCacheA read " + << datalen << "bytes" << std::endl; + return false; + } + + if (memcmp(wdata, data, wdatalen) != 0) + { + std::cerr << "SCardWriteCacheA / SCardReadCacheA data corruption detected" << std::endl; + return false; + } + + return true; +} + +static bool test_cache_w(SCARDCONTEXT context) +{ + BYTE wdata[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + const DWORD wdatalen = sizeof(wdata); + BYTE data[32] = {}; + DWORD datalen = sizeof(data); + LPWSTR name = L"testdata"; + UUID id = {}; + + auto rc = SCardWriteCacheW(context, &id, 0, name, wdata, wdatalen); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardWriteCacheW failed with " << err2str(rc) << std::endl; + return false; + } + + rc = SCardReadCacheW(context, &id, 0, name, data, &datalen); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardReadCacheW failed with " << err2str(rc) << std::endl; + return false; + } + + if (wdatalen != datalen) + { + std::cerr << "SCardReadCacheW wrote " << wdatalen << "bytes, SCardReadCacheW read " + << datalen << "bytes" << std::endl; + return false; + } + + if (memcmp(wdata, data, wdatalen) != 0) + { + std::cerr << "SCardReadCacheW / SCardReadCacheW data corruption detected" << std::endl; + return false; + } + + return true; +} + +static bool test_reader_icon_a(SCARDCONTEXT context) +{ + LPSTR name = "Gemalto PC Twin Reader 00 00\0\0"; + LPBYTE pbIcon = nullptr; + DWORD cbIcon = SCARD_AUTOALLOCATE; + + auto rc = SCardGetReaderIconA(context, name, reinterpret_cast(&pbIcon), &cbIcon); + SCardFreeMemory(context, pbIcon); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardGetReaderIconA failed with " << err2str(rc) << std::endl; + return false; + } + + return true; +} + +static bool test_reader_icon_w(SCARDCONTEXT context) +{ + LPWSTR name = L"Gemalto PC Twin Reader 00 00\0\0"; + LPBYTE pbIcon = nullptr; + DWORD cbIcon = SCARD_AUTOALLOCATE; + + auto rc = SCardGetReaderIconW(context, name, reinterpret_cast(&pbIcon), &cbIcon); + SCardFreeMemory(context, pbIcon); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardGetReaderIconW failed with " << err2str(rc) << std::endl; + return false; + } + + return true; +} + +static bool test_locate_cards_a(SCARDCONTEXT context) +{ + LPSTR name = "Gemalto PC Twin Reader 00 00\0\0"; + SCARD_READERSTATEA rgReaderStates[16] = {}; + + auto rc = SCardLocateCardsA(context, name, rgReaderStates, ARRAYSIZE(rgReaderStates)); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardLocateCardsA failed with " << err2str(rc) << std::endl; + return false; + } + + return true; +} + +static bool test_locate_cards_w(SCARDCONTEXT context) +{ + LPWSTR name = L"Gemalto PC Twin Reader 00 00\0\0"; + SCARD_READERSTATEW rgReaderStates[16] = {}; + + auto rc = SCardLocateCardsW(context, name, rgReaderStates, ARRAYSIZE(rgReaderStates)); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardLocateCardsW failed with " << err2str(rc) << std::endl; + return false; + } + + return true; +} + +static bool test_locate_cards_by_atr_a(SCARDCONTEXT context) +{ + SCARD_READERSTATEA rgReaderStates[16] = {}; + SCARD_ATRMASK rgAtrMasks[16] = {}; + + auto rc = SCardLocateCardsByATRA(context, rgAtrMasks, ARRAYSIZE(rgAtrMasks), rgReaderStates, + ARRAYSIZE(rgReaderStates)); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardLocateCardsByATRA failed with " << err2str(rc) << std::endl; + return false; + } + + return true; +} + +static bool test_locate_cards_by_atr_w(SCARDCONTEXT context) +{ + SCARD_READERSTATEW rgReaderStates[16] = {}; + SCARD_ATRMASK rgAtrMasks[16] = {}; + + auto rc = SCardLocateCardsByATRW(context, rgAtrMasks, ARRAYSIZE(rgAtrMasks), rgReaderStates, + ARRAYSIZE(rgReaderStates)); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardLocateCardsByATRW failed with " << err2str(rc) << std::endl; + return false; + } + + return true; +} + +static bool test_devicetype_id_a(SCARDCONTEXT context) +{ + BYTE data[32] = {}; + LPSTR name = "testdata"; + DWORD type; + + auto rc = SCardGetDeviceTypeIdA(context, name, &type); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardGetDeviceTypeIdA failed with " << err2str(rc) << std::endl; + return false; + } + + return true; +} + +static bool test_devicetype_id_w(SCARDCONTEXT context) +{ + BYTE data[32] = {}; + LPWSTR name = L"testdata"; + DWORD type; + + auto rc = SCardGetDeviceTypeIdW(context, name, &type); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardGetDeviceTypeIdW failed with " << err2str(rc) << std::endl; + return false; + } + + return true; +} + +static bool test_transmitcount(SCARDHANDLE handle) +{ + BYTE data[32] = {}; + LPWSTR name = L"testdata"; + DWORD count; + + auto rc = SCardGetTransmitCount(handle, &count); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardGetTransmitCount failed with " << err2str(rc) << std::endl; + return false; + } + std::cout << "SCardGetTransmitCount() " << count << std::endl; + return true; +} + +static bool test_status_a(SCARDHANDLE handle) +{ + BYTE data[32] = {}; + LPWSTR name = L"testdata"; + DWORD count; + /* + auto rc = SCardStatusA(handle, names, len, &state, &protocol, attr, &attrlen); + if (rc != SCARD_S_SUCCESS) { + std::cerr << "SCardGetDeviceTypeIdW failed with " << err2str(rc) << std::endl; + return false; + } + */ + return true; +} + +static bool test_status_w(SCARDHANDLE handle) +{ + BYTE data[32] = {}; + LPWSTR name = L"testdata"; + DWORD count; + /* + auto rc = SCardStatusA(handle, names, len, &state, &protocol, attr, &attrlen); + if (rc != SCARD_S_SUCCESS) { + std::cerr << "SCardGetDeviceTypeIdW failed with " << err2str(rc) << std::endl; + return false; + } +*/ + return true; +} + +static bool test_get_attrib(SCARDCONTEXT context, SCARDHANDLE handle) +{ + DWORD attrlen = SCARD_AUTOALLOCATE; + LPBYTE attr = nullptr; + + auto rc = + SCardGetAttrib(handle, SCARD_ATTR_ATR_STRING, reinterpret_cast(&attr), &attrlen); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardGetAttrib failed with " << err2str(rc) << std::endl; + return false; + } + std::cout << "SCardGetAttrib [" << attrlen << "]: " << (char*)attr << std::endl; + SCardFreeMemory(context, attr); + + return true; +} + +static bool test_set_attrib(SCARDCONTEXT context, SCARDHANDLE handle) +{ + DWORD attrlen = SCARD_AUTOALLOCATE; + BYTE attr[] = "0123456789"; + + auto rc = SCardSetAttrib(handle, SCARD_ATTR_SUPRESS_T1_IFS_REQUEST, attr, ARRAYSIZE(attr)); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardSetAttrib failed with " << err2str(rc) << std::endl; + return false; + } + std::cout << "SCardSetAttrib [" << attrlen << "]: " << (char*)attr << std::endl; + SCardFreeMemory(context, attr); + + return true; +} + +int main() +{ + std::cout << "Hello World!" << std::endl; + try + { + auto scopes = { SCARD_SCOPE_USER, SCARD_SCOPE_SYSTEM }; + for (auto scope : scopes) + { + SCARDCONTEXT context; + auto rc = SCardEstablishContext(scope, nullptr, nullptr, &context); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardEstablishContext [" << scope2str(scope) << "] failed with " + << err2str(rc) << std::endl; + } + else + { + std::cerr << "SCardEstablishContext [" << scope2str(scope) << "] success" + << std::endl; + + test_valid(context); + + test_list_reader_groups_a(context); + test_list_reader_groups_w(context); + + test_list_readers_a(context); + test_list_readers_w(context); + + test_list_cards_a(context); + test_list_cards_w(context); + + test_introduce_forget_reader_groups_a(context); + test_introduce_forget_reader_groups_w(context); + + test_introduce_forget_reader_a(context); + test_introduce_forget_reader_w(context); + + // TODO: Introduce/Remove reader to group + test_locate_cards_a(context); + test_locate_cards_w(context); + + test_locate_cards_by_atr_a(context); + test_locate_cards_by_atr_w(context); + + test_cache_a(context); + test_cache_w(context); + + test_reader_icon_a(context); + test_reader_icon_w(context); + + test_devicetype_id_a(context); + test_devicetype_id_w(context); + + // TODO: statuschange + // TODO: begin/end transaction + // TODO: state + // TODO: transmit + // TODO: control + + { + DWORD protocol; + SCARDHANDLE handle = 0; + LPSTR mszReaders; + DWORD chReaders = SCARD_AUTOALLOCATE; + + LONG status = SCardListReadersA( + context, nullptr, reinterpret_cast(&mszReaders), &chReaders); + if (status == SCARD_S_SUCCESS) + status = SCardConnectA(context, mszReaders, SCARD_SHARE_SHARED, + SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1 | + SCARD_PROTOCOL_Tx | SCARD_PROTOCOL_RAW, + &handle, &protocol); + SCardFreeMemory(context, mszReaders); + if (status != SCARD_S_SUCCESS) + { + std::cerr << "SCardConnectA [" + << "] failed with " << err2str(status) << std::endl; + } + else + { + test_status_a(handle); + test_status_w(handle); + test_get_attrib(context, handle); + test_set_attrib(context, handle); + test_transmitcount(handle); + + status = SCardDisconnect(handle, 0); + if (status) + { + std::cerr << "SCardDisconnect [" + << "] failed with " << err2str(status) << std::endl; + } + } + } + { + DWORD protocol; + SCARDHANDLE handle = 0; + LPWSTR mszReaders; + DWORD chReaders = SCARD_AUTOALLOCATE; + + LONG status = SCardListReadersW( + context, nullptr, reinterpret_cast(&mszReaders), &chReaders); + if (status == SCARD_S_SUCCESS) + status = SCardConnectW(context, mszReaders, SCARD_SHARE_SHARED, + SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1 | + SCARD_PROTOCOL_Tx | SCARD_PROTOCOL_RAW, + &handle, &protocol); + SCardFreeMemory(context, mszReaders); + + if (status != SCARD_S_SUCCESS) + { + std::cerr << "SCardConnectW [" + << "] failed with " << err2str(status) << std::endl; + } + else + { + test_status_a(handle); + test_status_w(handle); + test_get_attrib(context, handle); + test_set_attrib(context, handle); + test_transmitcount(handle); + + status = SCardDisconnect(handle, 0); + if (status) + { + std::cerr << "SCardDisconnect [" + << "] failed with " << err2str(status) << std::endl; + } + } + } + + rc = SCardReleaseContext(context); + if (rc != SCARD_S_SUCCESS) + { + std::cerr << "SCardReleaseContext [" << scope2str(scope) << "] failed with " + << err2str(rc) << std::endl; + } + } + } + } + catch (...) + { + std::cerr << "exception!!!!" << std::endl; + } + + return 0; +} diff --git a/winpr/include/winpr/smartcard.h b/winpr/include/winpr/smartcard.h index 721033a92..e19a6ee02 100644 --- a/winpr/include/winpr/smartcard.h +++ b/winpr/include/winpr/smartcard.h @@ -3,6 +3,8 @@ * Smart Card API * * Copyright 2014 Marc-Andre Moreau + * Copyright 2020 Armin Novak + * Copyright 2020 Thincast Technologies GmbH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -106,14 +108,14 @@ #define SCARD_ATR_LENGTH 33 -#define SCARD_PROTOCOL_UNDEFINED 0x00000000 -#define SCARD_PROTOCOL_T0 0x00000001 -#define SCARD_PROTOCOL_T1 0x00000002 -#define SCARD_PROTOCOL_RAW 0x00010000 +#define SCARD_PROTOCOL_UNDEFINED 0x00000000u +#define SCARD_PROTOCOL_T0 0x00000001u +#define SCARD_PROTOCOL_T1 0x00000002u +#define SCARD_PROTOCOL_RAW 0x00010000u #define SCARD_PROTOCOL_Tx (SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1) -#define SCARD_PROTOCOL_DEFAULT 0x80000000 -#define SCARD_PROTOCOL_OPTIMAL 0x00000000 +#define SCARD_PROTOCOL_DEFAULT 0x80000000u +#define SCARD_PROTOCOL_OPTIMAL 0x00000000u #define SCARD_POWER_DOWN 0 #define SCARD_COLD_RESET 1 @@ -681,7 +683,7 @@ extern "C" WINSCARDAPI LONG WINAPI SCardForgetCardTypeA(SCARDCONTEXT hContext, LPCSTR szCardName); WINSCARDAPI LONG WINAPI SCardForgetCardTypeW(SCARDCONTEXT hContext, LPCWSTR szCardName); - WINSCARDAPI LONG WINAPI SCardFreeMemory(SCARDCONTEXT hContext, LPCVOID pvMem); + WINSCARDAPI LONG WINAPI SCardFreeMemory(SCARDCONTEXT hContext, LPVOID pvMem); WINSCARDAPI HANDLE WINAPI SCardAccessStartedEvent(void); @@ -959,7 +961,7 @@ typedef LONG(WINAPI* fnSCardSetCardTypeProviderNameW)(SCARDCONTEXT hContext, LPC typedef LONG(WINAPI* fnSCardForgetCardTypeA)(SCARDCONTEXT hContext, LPCSTR szCardName); typedef LONG(WINAPI* fnSCardForgetCardTypeW)(SCARDCONTEXT hContext, LPCWSTR szCardName); -typedef LONG(WINAPI* fnSCardFreeMemory)(SCARDCONTEXT hContext, LPCVOID pvMem); +typedef LONG(WINAPI* fnSCardFreeMemory)(SCARDCONTEXT hContext, LPVOID pvMem); typedef HANDLE(WINAPI* fnSCardAccessStartedEvent)(void); diff --git a/winpr/libwinpr/smartcard/smartcard.c b/winpr/libwinpr/smartcard/smartcard.c index 4b67ea653..22d6b03ed 100644 --- a/winpr/libwinpr/smartcard/smartcard.c +++ b/winpr/libwinpr/smartcard/smartcard.c @@ -3,6 +3,8 @@ * Smart Card API * * Copyright 2014 Marc-Andre Moreau + * Copyright 2020 Armin Novak + * Copyright 2020 Thincast Technologies GmbH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,7 +36,7 @@ #include "smartcard_inspect.h" static INIT_ONCE g_Initialized = INIT_ONCE_STATIC_INIT; -static PSCardApiFunctionTable g_SCardApi = NULL; +static const SCardApiFunctionTable* g_SCardApi = NULL; #define TAG WINPR_TAG("smartcard") @@ -296,7 +298,7 @@ WINSCARDAPI LONG WINAPI SCardForgetCardTypeW(SCARDCONTEXT hContext, LPCWSTR szCa SCARDAPI_STUB_CALL_LONG(SCardForgetCardTypeW, hContext, szCardName); } -WINSCARDAPI LONG WINAPI SCardFreeMemory(SCARDCONTEXT hContext, LPCVOID pvMem) +WINSCARDAPI LONG WINAPI SCardFreeMemory(SCARDCONTEXT hContext, LPVOID pvMem) { SCARDAPI_STUB_CALL_LONG(SCardFreeMemory, hContext, pvMem); } diff --git a/winpr/libwinpr/smartcard/smartcard_inspect.c b/winpr/libwinpr/smartcard/smartcard_inspect.c index 76addfbfc..b80bb859b 100644 --- a/winpr/libwinpr/smartcard/smartcard_inspect.c +++ b/winpr/libwinpr/smartcard/smartcard_inspect.c @@ -3,6 +3,8 @@ * Smart Card API * * Copyright 2014 Marc-Andre Moreau + * Copyright 2020 Armin Novak + * Copyright 2020 Thincast Technologies GmbH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,9 +32,10 @@ #include "smartcard_inspect.h" +static const DWORD g_LogLevel = WLOG_DEBUG; static wLog* g_Log = NULL; -static PSCardApiFunctionTable g_SCardApi = NULL; +static const SCardApiFunctionTable* g_SCardApi = NULL; /** * Standard Windows Smart Card API @@ -43,12 +46,12 @@ static LONG WINAPI Inspect_SCardEstablishContext(DWORD dwScope, LPCVOID pvReserv { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardEstablishContext { dwScope: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardEstablishContext { dwScope: %s (0x%08" PRIX32 ")", SCardGetScopeString(dwScope), dwScope); status = g_SCardApi->pfnSCardEstablishContext(dwScope, pvReserved1, pvReserved2, phContext); - WLog_Print(g_Log, WLOG_DEBUG, "SCardEstablishContext } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardEstablishContext } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -58,11 +61,11 @@ static LONG WINAPI Inspect_SCardReleaseContext(SCARDCONTEXT hContext) { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardReleaseContext { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardReleaseContext { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardReleaseContext(hContext); - WLog_Print(g_Log, WLOG_DEBUG, "SCardReleaseContext } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardReleaseContext } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -72,11 +75,11 @@ static LONG WINAPI Inspect_SCardIsValidContext(SCARDCONTEXT hContext) { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardIsValidContext { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardIsValidContext { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardIsValidContext(hContext); - WLog_Print(g_Log, WLOG_DEBUG, "SCardIsValidContext } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardIsValidContext } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -87,11 +90,11 @@ static LONG WINAPI Inspect_SCardListReaderGroupsA(SCARDCONTEXT hContext, LPSTR m { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardListReaderGroupsA { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardListReaderGroupsA { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardListReaderGroupsA(hContext, mszGroups, pcchGroups); - WLog_Print(g_Log, WLOG_DEBUG, "SCardListReaderGroupsA } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardListReaderGroupsA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -102,11 +105,11 @@ static LONG WINAPI Inspect_SCardListReaderGroupsW(SCARDCONTEXT hContext, LPWSTR { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardListReaderGroupsW { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardListReaderGroupsW { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardListReaderGroupsW(hContext, mszGroups, pcchGroups); - WLog_Print(g_Log, WLOG_DEBUG, "SCardListReaderGroupsW } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardListReaderGroupsW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -117,11 +120,11 @@ static LONG WINAPI Inspect_SCardListReadersA(SCARDCONTEXT hContext, LPCSTR mszGr { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardListReadersA { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardListReadersA { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardListReadersA(hContext, mszGroups, mszReaders, pcchReaders); - WLog_Print(g_Log, WLOG_DEBUG, "SCardListReadersA } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardListReadersA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -131,12 +134,10 @@ static LONG WINAPI Inspect_SCardListReadersW(SCARDCONTEXT hContext, LPCWSTR mszG LPWSTR mszReaders, LPDWORD pcchReaders) { LONG status; - - WLog_Print(g_Log, WLOG_DEBUG, "SCardListReadersW { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardListReadersW { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardListReadersW(hContext, mszGroups, mszReaders, pcchReaders); - - WLog_Print(g_Log, WLOG_DEBUG, "SCardListReadersW } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardListReadersW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -148,12 +149,12 @@ static LONG WINAPI Inspect_SCardListCardsA(SCARDCONTEXT hContext, LPCBYTE pbAtr, { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardListCardsA { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardListCardsA { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardListCardsA(hContext, pbAtr, rgquidInterfaces, cguidInterfaceCount, mszCards, pcchCards); - WLog_Print(g_Log, WLOG_DEBUG, "SCardListCardsA } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardListCardsA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -165,12 +166,12 @@ static LONG WINAPI Inspect_SCardListCardsW(SCARDCONTEXT hContext, LPCBYTE pbAtr, { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardListCardsW { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardListCardsW { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardListCardsW(hContext, pbAtr, rgquidInterfaces, cguidInterfaceCount, mszCards, pcchCards); - WLog_Print(g_Log, WLOG_DEBUG, "SCardListCardsW } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardListCardsW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -181,12 +182,12 @@ static LONG WINAPI Inspect_SCardListInterfacesA(SCARDCONTEXT hContext, LPCSTR sz { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardListInterfacesA { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardListInterfacesA { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardListInterfacesA(hContext, szCard, pguidInterfaces, pcguidInterfaces); - WLog_Print(g_Log, WLOG_DEBUG, "SCardListInterfacesA } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardListInterfacesA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -197,12 +198,12 @@ static LONG WINAPI Inspect_SCardListInterfacesW(SCARDCONTEXT hContext, LPCWSTR s { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardListInterfacesW { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardListInterfacesW { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardListInterfacesW(hContext, szCard, pguidInterfaces, pcguidInterfaces); - WLog_Print(g_Log, WLOG_DEBUG, "SCardListInterfacesW } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardListInterfacesW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -213,11 +214,11 @@ static LONG WINAPI Inspect_SCardGetProviderIdA(SCARDCONTEXT hContext, LPCSTR szC { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardGetProviderIdA { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardGetProviderIdA { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardGetProviderIdA(hContext, szCard, pguidProviderId); - WLog_Print(g_Log, WLOG_DEBUG, "SCardGetProviderIdA } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardGetProviderIdA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -228,11 +229,11 @@ static LONG WINAPI Inspect_SCardGetProviderIdW(SCARDCONTEXT hContext, LPCWSTR sz { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardGetProviderIdW { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardGetProviderIdW { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardGetProviderIdW(hContext, szCard, pguidProviderId); - WLog_Print(g_Log, WLOG_DEBUG, "SCardGetProviderIdW } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardGetProviderIdW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -244,12 +245,12 @@ static LONG WINAPI Inspect_SCardGetCardTypeProviderNameA(SCARDCONTEXT hContext, { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardGetCardTypeProviderNameA { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardGetCardTypeProviderNameA { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardGetCardTypeProviderNameA(hContext, szCardName, dwProviderId, szProvider, pcchProvider); - WLog_Print(g_Log, WLOG_DEBUG, "SCardGetCardTypeProviderNameA } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardGetCardTypeProviderNameA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -261,12 +262,12 @@ static LONG WINAPI Inspect_SCardGetCardTypeProviderNameW(SCARDCONTEXT hContext, { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardGetCardTypeProviderNameW { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardGetCardTypeProviderNameW { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardGetCardTypeProviderNameW(hContext, szCardName, dwProviderId, szProvider, pcchProvider); - WLog_Print(g_Log, WLOG_DEBUG, "SCardGetCardTypeProviderNameW } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardGetCardTypeProviderNameW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -276,11 +277,11 @@ static LONG WINAPI Inspect_SCardIntroduceReaderGroupA(SCARDCONTEXT hContext, LPC { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardIntroduceReaderGroupA { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardIntroduceReaderGroupA { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardIntroduceReaderGroupA(hContext, szGroupName); - WLog_Print(g_Log, WLOG_DEBUG, "SCardIntroduceReaderGroupA } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardIntroduceReaderGroupA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -290,11 +291,11 @@ static LONG WINAPI Inspect_SCardIntroduceReaderGroupW(SCARDCONTEXT hContext, LPC { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardIntroduceReaderGroupW { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardIntroduceReaderGroupW { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardIntroduceReaderGroupW(hContext, szGroupName); - WLog_Print(g_Log, WLOG_DEBUG, "SCardIntroduceReaderGroupW } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardIntroduceReaderGroupW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -304,11 +305,11 @@ static LONG WINAPI Inspect_SCardForgetReaderGroupA(SCARDCONTEXT hContext, LPCSTR { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardForgetReaderGroupA { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardForgetReaderGroupA { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardForgetReaderGroupA(hContext, szGroupName); - WLog_Print(g_Log, WLOG_DEBUG, "SCardForgetReaderGroupA } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardForgetReaderGroupA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -318,11 +319,11 @@ static LONG WINAPI Inspect_SCardForgetReaderGroupW(SCARDCONTEXT hContext, LPCWST { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardForgetReaderGroupW { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardForgetReaderGroupW { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardForgetReaderGroupW(hContext, szGroupName); - WLog_Print(g_Log, WLOG_DEBUG, "SCardForgetReaderGroupW } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardForgetReaderGroupW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -333,11 +334,11 @@ static LONG WINAPI Inspect_SCardIntroduceReaderA(SCARDCONTEXT hContext, LPCSTR s { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardIntroduceReaderA { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardIntroduceReaderA { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardIntroduceReaderA(hContext, szReaderName, szDeviceName); - WLog_Print(g_Log, WLOG_DEBUG, "SCardIntroduceReaderA } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardIntroduceReaderA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -348,11 +349,11 @@ static LONG WINAPI Inspect_SCardIntroduceReaderW(SCARDCONTEXT hContext, LPCWSTR { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardIntroduceReaderW { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardIntroduceReaderW { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardIntroduceReaderW(hContext, szReaderName, szDeviceName); - WLog_Print(g_Log, WLOG_DEBUG, "SCardIntroduceReaderW } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardIntroduceReaderW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -362,11 +363,11 @@ static LONG WINAPI Inspect_SCardForgetReaderA(SCARDCONTEXT hContext, LPCSTR szRe { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardForgetReaderA { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardForgetReaderA { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardForgetReaderA(hContext, szReaderName); - WLog_Print(g_Log, WLOG_DEBUG, "SCardForgetReaderA } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardForgetReaderA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -376,11 +377,11 @@ static LONG WINAPI Inspect_SCardForgetReaderW(SCARDCONTEXT hContext, LPCWSTR szR { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardForgetReaderW { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardForgetReaderW { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardForgetReaderW(hContext, szReaderName); - WLog_Print(g_Log, WLOG_DEBUG, "SCardForgetReaderW } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardForgetReaderW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -391,11 +392,11 @@ static LONG WINAPI Inspect_SCardAddReaderToGroupA(SCARDCONTEXT hContext, LPCSTR { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardAddReaderToGroupA { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardAddReaderToGroupA { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardAddReaderToGroupA(hContext, szReaderName, szGroupName); - WLog_Print(g_Log, WLOG_DEBUG, "SCardAddReaderToGroupA } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardAddReaderToGroupA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -406,11 +407,11 @@ static LONG WINAPI Inspect_SCardAddReaderToGroupW(SCARDCONTEXT hContext, LPCWSTR { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardAddReaderToGroupW { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardAddReaderToGroupW { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardAddReaderToGroupW(hContext, szReaderName, szGroupName); - WLog_Print(g_Log, WLOG_DEBUG, "SCardAddReaderToGroupW } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardAddReaderToGroupW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -421,11 +422,11 @@ static LONG WINAPI Inspect_SCardRemoveReaderFromGroupA(SCARDCONTEXT hContext, LP { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardRemoveReaderFromGroupA { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardRemoveReaderFromGroupA { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardRemoveReaderFromGroupA(hContext, szReaderName, szGroupName); - WLog_Print(g_Log, WLOG_DEBUG, "SCardRemoveReaderFromGroupA } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardRemoveReaderFromGroupA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -436,11 +437,11 @@ static LONG WINAPI Inspect_SCardRemoveReaderFromGroupW(SCARDCONTEXT hContext, LP { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardRemoveReaderFromGroupW { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardRemoveReaderFromGroupW { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardRemoveReaderFromGroupW(hContext, szReaderName, szGroupName); - WLog_Print(g_Log, WLOG_DEBUG, "SCardRemoveReaderFromGroupW } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardRemoveReaderFromGroupW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -453,13 +454,13 @@ static LONG WINAPI Inspect_SCardIntroduceCardTypeA(SCARDCONTEXT hContext, LPCSTR { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardIntroduceCardTypeA { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardIntroduceCardTypeA { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardIntroduceCardTypeA(hContext, szCardName, pguidPrimaryProvider, rgguidInterfaces, dwInterfaceCount, pbAtr, pbAtrMask, cbAtrLen); - WLog_Print(g_Log, WLOG_DEBUG, "SCardIntroduceCardTypeA } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardIntroduceCardTypeA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -472,13 +473,13 @@ static LONG WINAPI Inspect_SCardIntroduceCardTypeW(SCARDCONTEXT hContext, LPCWST { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardIntroduceCardTypeW { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardIntroduceCardTypeW { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardIntroduceCardTypeW(hContext, szCardName, pguidPrimaryProvider, rgguidInterfaces, dwInterfaceCount, pbAtr, pbAtrMask, cbAtrLen); - WLog_Print(g_Log, WLOG_DEBUG, "SCardIntroduceCardTypeW } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardIntroduceCardTypeW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -489,12 +490,12 @@ static LONG WINAPI Inspect_SCardSetCardTypeProviderNameA(SCARDCONTEXT hContext, { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardSetCardTypeProviderNameA { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardSetCardTypeProviderNameA { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardSetCardTypeProviderNameA(hContext, szCardName, dwProviderId, szProvider); - WLog_Print(g_Log, WLOG_DEBUG, "SCardSetCardTypeProviderNameA } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardSetCardTypeProviderNameA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -505,12 +506,12 @@ static LONG WINAPI Inspect_SCardSetCardTypeProviderNameW(SCARDCONTEXT hContext, { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardSetCardTypeProviderNameA { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardSetCardTypeProviderNameA { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardSetCardTypeProviderNameW(hContext, szCardName, dwProviderId, szProvider); - WLog_Print(g_Log, WLOG_DEBUG, "SCardSetCardTypeProviderNameW } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardSetCardTypeProviderNameW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -520,11 +521,11 @@ static LONG WINAPI Inspect_SCardForgetCardTypeA(SCARDCONTEXT hContext, LPCSTR sz { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardForgetCardTypeA { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardForgetCardTypeA { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardForgetCardTypeA(hContext, szCardName); - WLog_Print(g_Log, WLOG_DEBUG, "SCardForgetCardTypeA } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardForgetCardTypeA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -534,25 +535,25 @@ static LONG WINAPI Inspect_SCardForgetCardTypeW(SCARDCONTEXT hContext, LPCWSTR s { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardForgetCardTypeW { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardForgetCardTypeW { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardForgetCardTypeW(hContext, szCardName); - WLog_Print(g_Log, WLOG_DEBUG, "SCardForgetCardTypeW } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardForgetCardTypeW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; } -static LONG WINAPI Inspect_SCardFreeMemory(SCARDCONTEXT hContext, LPCVOID pvMem) +static LONG WINAPI Inspect_SCardFreeMemory(SCARDCONTEXT hContext, LPVOID pvMem) { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardFreeMemory { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardFreeMemory { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardFreeMemory(hContext, pvMem); - WLog_Print(g_Log, WLOG_DEBUG, "SCardFreeMemory } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardFreeMemory } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -562,22 +563,22 @@ static HANDLE WINAPI Inspect_SCardAccessStartedEvent(void) { HANDLE hEvent; - WLog_Print(g_Log, WLOG_DEBUG, "SCardAccessStartedEvent {"); + WLog_Print(g_Log, g_LogLevel, "SCardAccessStartedEvent {"); hEvent = g_SCardApi->pfnSCardAccessStartedEvent(); - WLog_Print(g_Log, WLOG_DEBUG, "SCardAccessStartedEvent } hEvent: %p", hEvent); + WLog_Print(g_Log, g_LogLevel, "SCardAccessStartedEvent } hEvent: %p", hEvent); return hEvent; } static void WINAPI Inspect_SCardReleaseStartedEvent(void) { - WLog_Print(g_Log, WLOG_DEBUG, "SCardReleaseStartedEvent {"); + WLog_Print(g_Log, g_LogLevel, "SCardReleaseStartedEvent {"); g_SCardApi->pfnSCardReleaseStartedEvent(); - WLog_Print(g_Log, WLOG_DEBUG, "SCardReleaseStartedEvent }"); + WLog_Print(g_Log, g_LogLevel, "SCardReleaseStartedEvent }"); } static LONG WINAPI Inspect_SCardLocateCardsA(SCARDCONTEXT hContext, LPCSTR mszCards, @@ -585,11 +586,11 @@ static LONG WINAPI Inspect_SCardLocateCardsA(SCARDCONTEXT hContext, LPCSTR mszCa { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardLocateCardsA { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardLocateCardsA { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardLocateCardsA(hContext, mszCards, rgReaderStates, cReaders); - WLog_Print(g_Log, WLOG_DEBUG, "SCardLocateCardsA } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardLocateCardsA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -600,11 +601,11 @@ static LONG WINAPI Inspect_SCardLocateCardsW(SCARDCONTEXT hContext, LPCWSTR mszC { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardLocateCardsW { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardLocateCardsW { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardLocateCardsW(hContext, mszCards, rgReaderStates, cReaders); - WLog_Print(g_Log, WLOG_DEBUG, "SCardLocateCardsW } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardLocateCardsW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -616,12 +617,12 @@ static LONG WINAPI Inspect_SCardLocateCardsByATRA(SCARDCONTEXT hContext, LPSCARD { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardLocateCardsByATRA { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardLocateCardsByATRA { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardLocateCardsByATRA(hContext, rgAtrMasks, cAtrs, rgReaderStates, cReaders); - WLog_Print(g_Log, WLOG_DEBUG, "SCardLocateCardsByATRA } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardLocateCardsByATRA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -633,12 +634,12 @@ static LONG WINAPI Inspect_SCardLocateCardsByATRW(SCARDCONTEXT hContext, LPSCARD { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardLocateCardsByATRW { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardLocateCardsByATRW { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardLocateCardsByATRW(hContext, rgAtrMasks, cAtrs, rgReaderStates, cReaders); - WLog_Print(g_Log, WLOG_DEBUG, "SCardLocateCardsByATRW } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardLocateCardsByATRW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -650,11 +651,11 @@ static LONG WINAPI Inspect_SCardGetStatusChangeA(SCARDCONTEXT hContext, DWORD dw { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardGetStatusChangeA { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardGetStatusChangeA { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardGetStatusChangeA(hContext, dwTimeout, rgReaderStates, cReaders); - WLog_Print(g_Log, WLOG_DEBUG, "SCardGetStatusChangeA } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardGetStatusChangeA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -666,11 +667,11 @@ static LONG WINAPI Inspect_SCardGetStatusChangeW(SCARDCONTEXT hContext, DWORD dw { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardGetStatusChangeW { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardGetStatusChangeW { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardGetStatusChangeW(hContext, dwTimeout, rgReaderStates, cReaders); - WLog_Print(g_Log, WLOG_DEBUG, "SCardGetStatusChangeW } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardGetStatusChangeW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -680,11 +681,11 @@ static LONG WINAPI Inspect_SCardCancel(SCARDCONTEXT hContext) { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardCancel { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardCancel { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardCancel(hContext); - WLog_Print(g_Log, WLOG_DEBUG, "SCardCancel } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardCancel } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -696,12 +697,12 @@ static LONG WINAPI Inspect_SCardConnectA(SCARDCONTEXT hContext, LPCSTR szReader, { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardConnectA { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardConnectA { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardConnectA(hContext, szReader, dwShareMode, dwPreferredProtocols, phCard, pdwActiveProtocol); - WLog_Print(g_Log, WLOG_DEBUG, "SCardConnectA } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardConnectA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -713,12 +714,12 @@ static LONG WINAPI Inspect_SCardConnectW(SCARDCONTEXT hContext, LPCWSTR szReader { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardConnectW { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardConnectW { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardConnectW(hContext, szReader, dwShareMode, dwPreferredProtocols, phCard, pdwActiveProtocol); - WLog_Print(g_Log, WLOG_DEBUG, "SCardConnectW } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardConnectW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -730,12 +731,12 @@ static LONG WINAPI Inspect_SCardReconnect(SCARDHANDLE hCard, DWORD dwShareMode, { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardReconnect { hCard: %p", (void*)hCard); + WLog_Print(g_Log, g_LogLevel, "SCardReconnect { hCard: %p", (void*)hCard); status = g_SCardApi->pfnSCardReconnect(hCard, dwShareMode, dwPreferredProtocols, dwInitialization, pdwActiveProtocol); - WLog_Print(g_Log, WLOG_DEBUG, "SCardReconnect } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardReconnect } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -745,11 +746,11 @@ static LONG WINAPI Inspect_SCardDisconnect(SCARDHANDLE hCard, DWORD dwDispositio { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardDisconnect { hCard: %p", (void*)hCard); + WLog_Print(g_Log, g_LogLevel, "SCardDisconnect { hCard: %p", (void*)hCard); status = g_SCardApi->pfnSCardDisconnect(hCard, dwDisposition); - WLog_Print(g_Log, WLOG_DEBUG, "SCardDisconnect } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardDisconnect } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -759,11 +760,11 @@ static LONG WINAPI Inspect_SCardBeginTransaction(SCARDHANDLE hCard) { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardBeginTransaction { hCard: %p", (void*)hCard); + WLog_Print(g_Log, g_LogLevel, "SCardBeginTransaction { hCard: %p", (void*)hCard); status = g_SCardApi->pfnSCardBeginTransaction(hCard); - WLog_Print(g_Log, WLOG_DEBUG, "SCardBeginTransaction } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardBeginTransaction } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -773,11 +774,11 @@ static LONG WINAPI Inspect_SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDispos { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardEndTransaction { hCard: %p", (void*)hCard); + WLog_Print(g_Log, g_LogLevel, "SCardEndTransaction { hCard: %p", (void*)hCard); status = g_SCardApi->pfnSCardEndTransaction(hCard, dwDisposition); - WLog_Print(g_Log, WLOG_DEBUG, "SCardEndTransaction } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardEndTransaction } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -787,11 +788,11 @@ static LONG WINAPI Inspect_SCardCancelTransaction(SCARDHANDLE hCard) { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardCancelTransaction { hCard: %p", (void*)hCard); + WLog_Print(g_Log, g_LogLevel, "SCardCancelTransaction { hCard: %p", (void*)hCard); status = g_SCardApi->pfnSCardCancelTransaction(hCard); - WLog_Print(g_Log, WLOG_DEBUG, "SCardCancelTransaction } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardCancelTransaction } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -802,11 +803,11 @@ static LONG WINAPI Inspect_SCardState(SCARDHANDLE hCard, LPDWORD pdwState, LPDWO { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardState { hCard: %p", (void*)hCard); + WLog_Print(g_Log, g_LogLevel, "SCardState { hCard: %p", (void*)hCard); status = g_SCardApi->pfnSCardState(hCard, pdwState, pdwProtocol, pbAtr, pcbAtrLen); - WLog_Print(g_Log, WLOG_DEBUG, "SCardState } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardState } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -818,12 +819,12 @@ static LONG WINAPI Inspect_SCardStatusA(SCARDHANDLE hCard, LPSTR mszReaderNames, { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardStatusA { hCard: %p", (void*)hCard); + WLog_Print(g_Log, g_LogLevel, "SCardStatusA { hCard: %p", (void*)hCard); status = g_SCardApi->pfnSCardStatusA(hCard, mszReaderNames, pcchReaderLen, pdwState, pdwProtocol, pbAtr, pcbAtrLen); - WLog_Print(g_Log, WLOG_DEBUG, "SCardStatusA } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardStatusA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -835,12 +836,12 @@ static LONG WINAPI Inspect_SCardStatusW(SCARDHANDLE hCard, LPWSTR mszReaderNames { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardStatusW { hCard: %p", (void*)hCard); + WLog_Print(g_Log, g_LogLevel, "SCardStatusW { hCard: %p", (void*)hCard); status = g_SCardApi->pfnSCardStatusW(hCard, mszReaderNames, pcchReaderLen, pdwState, pdwProtocol, pbAtr, pcbAtrLen); - WLog_Print(g_Log, WLOG_DEBUG, "SCardStatusW } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardStatusW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -853,12 +854,12 @@ static LONG WINAPI Inspect_SCardTransmit(SCARDHANDLE hCard, LPCSCARD_IO_REQUEST { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardTransmit { hCard: %p", (void*)hCard); + WLog_Print(g_Log, g_LogLevel, "SCardTransmit { hCard: %p", (void*)hCard); status = g_SCardApi->pfnSCardTransmit(hCard, pioSendPci, pbSendBuffer, cbSendLength, pioRecvPci, pbRecvBuffer, pcbRecvLength); - WLog_Print(g_Log, WLOG_DEBUG, "SCardTransmit } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardTransmit } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -868,11 +869,11 @@ static LONG WINAPI Inspect_SCardGetTransmitCount(SCARDHANDLE hCard, LPDWORD pcTr { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardGetTransmitCount { hCard: %p", (void*)hCard); + WLog_Print(g_Log, g_LogLevel, "SCardGetTransmitCount { hCard: %p", (void*)hCard); status = g_SCardApi->pfnSCardGetTransmitCount(hCard, pcTransmitCount); - WLog_Print(g_Log, WLOG_DEBUG, "SCardGetTransmitCount } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardGetTransmitCount } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -884,12 +885,12 @@ static LONG WINAPI Inspect_SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardControl { hCard: %p", (void*)hCard); + WLog_Print(g_Log, g_LogLevel, "SCardControl { hCard: %p", (void*)hCard); status = g_SCardApi->pfnSCardControl(hCard, dwControlCode, lpInBuffer, cbInBufferSize, lpOutBuffer, cbOutBufferSize, lpBytesReturned); - WLog_Print(g_Log, WLOG_DEBUG, "SCardControl } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardControl } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -900,11 +901,11 @@ static LONG WINAPI Inspect_SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPB { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardGetAttrib { hCard: %p", (void*)hCard); + WLog_Print(g_Log, g_LogLevel, "SCardGetAttrib { hCard: %p", (void*)hCard); status = g_SCardApi->pfnSCardGetAttrib(hCard, dwAttrId, pbAttr, pcbAttrLen); - WLog_Print(g_Log, WLOG_DEBUG, "SCardGetAttrib } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardGetAttrib } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -915,11 +916,11 @@ static LONG WINAPI Inspect_SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPC { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardSetAttrib { hCard: %p", (void*)hCard); + WLog_Print(g_Log, g_LogLevel, "SCardSetAttrib { hCard: %p", (void*)hCard); status = g_SCardApi->pfnSCardSetAttrib(hCard, dwAttrId, pbAttr, cbAttrLen); - WLog_Print(g_Log, WLOG_DEBUG, "SCardSetAttrib } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardSetAttrib } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -929,11 +930,11 @@ static LONG WINAPI Inspect_SCardUIDlgSelectCardA(LPOPENCARDNAMEA_EX pDlgStruc) { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardUIDlgSelectCardA {"); + WLog_Print(g_Log, g_LogLevel, "SCardUIDlgSelectCardA {"); status = g_SCardApi->pfnSCardUIDlgSelectCardA(pDlgStruc); - WLog_Print(g_Log, WLOG_DEBUG, "SCardUIDlgSelectCardA } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardUIDlgSelectCardA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -943,11 +944,11 @@ static LONG WINAPI Inspect_SCardUIDlgSelectCardW(LPOPENCARDNAMEW_EX pDlgStruc) { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardUIDlgSelectCardW {"); + WLog_Print(g_Log, g_LogLevel, "SCardUIDlgSelectCardW {"); status = g_SCardApi->pfnSCardUIDlgSelectCardW(pDlgStruc); - WLog_Print(g_Log, WLOG_DEBUG, "SCardUIDlgSelectCardW } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardUIDlgSelectCardW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -957,11 +958,11 @@ static LONG WINAPI Inspect_GetOpenCardNameA(LPOPENCARDNAMEA pDlgStruc) { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "GetOpenCardNameA {"); + WLog_Print(g_Log, g_LogLevel, "GetOpenCardNameA {"); status = g_SCardApi->pfnGetOpenCardNameA(pDlgStruc); - WLog_Print(g_Log, WLOG_DEBUG, "GetOpenCardNameA } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "GetOpenCardNameA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -971,11 +972,11 @@ static LONG WINAPI Inspect_GetOpenCardNameW(LPOPENCARDNAMEW pDlgStruc) { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "GetOpenCardNameW {"); + WLog_Print(g_Log, g_LogLevel, "GetOpenCardNameW {"); status = g_SCardApi->pfnGetOpenCardNameW(pDlgStruc); - WLog_Print(g_Log, WLOG_DEBUG, "GetOpenCardNameW } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "GetOpenCardNameW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -985,11 +986,11 @@ static LONG WINAPI Inspect_SCardDlgExtendedError(void) { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardDlgExtendedError {"); + WLog_Print(g_Log, g_LogLevel, "SCardDlgExtendedError {"); status = g_SCardApi->pfnSCardDlgExtendedError(); - WLog_Print(g_Log, WLOG_DEBUG, "SCardDlgExtendedError } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardDlgExtendedError } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -1001,12 +1002,12 @@ static LONG WINAPI Inspect_SCardReadCacheA(SCARDCONTEXT hContext, UUID* CardIden { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardReadCacheA { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardReadCacheA { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardReadCacheA(hContext, CardIdentifier, FreshnessCounter, LookupName, Data, DataLen); - WLog_Print(g_Log, WLOG_DEBUG, "SCardReadCacheA } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardReadCacheA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -1018,12 +1019,12 @@ static LONG WINAPI Inspect_SCardReadCacheW(SCARDCONTEXT hContext, UUID* CardIden { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardReadCacheW { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardReadCacheW { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardReadCacheW(hContext, CardIdentifier, FreshnessCounter, LookupName, Data, DataLen); - WLog_Print(g_Log, WLOG_DEBUG, "SCardReadCacheW } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardReadCacheW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -1035,12 +1036,12 @@ static LONG WINAPI Inspect_SCardWriteCacheA(SCARDCONTEXT hContext, UUID* CardIde { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardWriteCacheA { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardWriteCacheA { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardWriteCacheA(hContext, CardIdentifier, FreshnessCounter, LookupName, Data, DataLen); - WLog_Print(g_Log, WLOG_DEBUG, "SCardWriteCacheA } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardWriteCacheA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -1052,12 +1053,12 @@ static LONG WINAPI Inspect_SCardWriteCacheW(SCARDCONTEXT hContext, UUID* CardIde { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardWriteCacheW { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardWriteCacheW { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardWriteCacheW(hContext, CardIdentifier, FreshnessCounter, LookupName, Data, DataLen); - WLog_Print(g_Log, WLOG_DEBUG, "SCardWriteCacheW } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardWriteCacheW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -1068,11 +1069,11 @@ static LONG WINAPI Inspect_SCardGetReaderIconA(SCARDCONTEXT hContext, LPCSTR szR { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardGetReaderIconA { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardGetReaderIconA { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardGetReaderIconA(hContext, szReaderName, pbIcon, pcbIcon); - WLog_Print(g_Log, WLOG_DEBUG, "SCardGetReaderIconA } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardGetReaderIconA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -1083,11 +1084,11 @@ static LONG WINAPI Inspect_SCardGetReaderIconW(SCARDCONTEXT hContext, LPCWSTR sz { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardGetReaderIconW { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardGetReaderIconW { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardGetReaderIconW(hContext, szReaderName, pbIcon, pcbIcon); - WLog_Print(g_Log, WLOG_DEBUG, "SCardGetReaderIconW } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardGetReaderIconW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -1098,11 +1099,11 @@ static LONG WINAPI Inspect_SCardGetDeviceTypeIdA(SCARDCONTEXT hContext, LPCSTR s { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardGetDeviceTypeIdA { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardGetDeviceTypeIdA { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardGetDeviceTypeIdA(hContext, szReaderName, pdwDeviceTypeId); - WLog_Print(g_Log, WLOG_DEBUG, "SCardGetDeviceTypeIdA } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardGetDeviceTypeIdA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -1113,11 +1114,11 @@ static LONG WINAPI Inspect_SCardGetDeviceTypeIdW(SCARDCONTEXT hContext, LPCWSTR { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardGetDeviceTypeIdW { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardGetDeviceTypeIdW { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardGetDeviceTypeIdW(hContext, szReaderName, pdwDeviceTypeId); - WLog_Print(g_Log, WLOG_DEBUG, "SCardGetDeviceTypeIdW } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardGetDeviceTypeIdW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -1130,13 +1131,13 @@ static LONG WINAPI Inspect_SCardGetReaderDeviceInstanceIdA(SCARDCONTEXT hContext { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardGetReaderDeviceInstanceIdA { hContext: %p", + WLog_Print(g_Log, g_LogLevel, "SCardGetReaderDeviceInstanceIdA { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardGetReaderDeviceInstanceIdA( hContext, szReaderName, szDeviceInstanceId, pcchDeviceInstanceId); - WLog_Print(g_Log, WLOG_DEBUG, "SCardGetReaderDeviceInstanceIdA } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardGetReaderDeviceInstanceIdA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -1149,13 +1150,13 @@ static LONG WINAPI Inspect_SCardGetReaderDeviceInstanceIdW(SCARDCONTEXT hContext { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardGetReaderDeviceInstanceIdW { hContext: %p", + WLog_Print(g_Log, g_LogLevel, "SCardGetReaderDeviceInstanceIdW { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardGetReaderDeviceInstanceIdW( hContext, szReaderName, szDeviceInstanceId, pcchDeviceInstanceId); - WLog_Print(g_Log, WLOG_DEBUG, "SCardGetReaderDeviceInstanceIdW } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardGetReaderDeviceInstanceIdW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -1168,13 +1169,13 @@ static LONG WINAPI Inspect_SCardListReadersWithDeviceInstanceIdA(SCARDCONTEXT hC { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardListReadersWithDeviceInstanceIdA { hContext: %p", + WLog_Print(g_Log, g_LogLevel, "SCardListReadersWithDeviceInstanceIdA { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardListReadersWithDeviceInstanceIdA(hContext, szDeviceInstanceId, mszReaders, pcchReaders); - WLog_Print(g_Log, WLOG_DEBUG, + WLog_Print(g_Log, g_LogLevel, "SCardListReadersWithDeviceInstanceIdA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); @@ -1188,13 +1189,13 @@ static LONG WINAPI Inspect_SCardListReadersWithDeviceInstanceIdW(SCARDCONTEXT hC { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardListReadersWithDeviceInstanceIdW { hContext: %p", + WLog_Print(g_Log, g_LogLevel, "SCardListReadersWithDeviceInstanceIdW { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardListReadersWithDeviceInstanceIdW(hContext, szDeviceInstanceId, mszReaders, pcchReaders); - WLog_Print(g_Log, WLOG_DEBUG, + WLog_Print(g_Log, g_LogLevel, "SCardListReadersWithDeviceInstanceIdW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); @@ -1205,11 +1206,11 @@ static LONG WINAPI Inspect_SCardAudit(SCARDCONTEXT hContext, DWORD dwEvent) { LONG status; - WLog_Print(g_Log, WLOG_DEBUG, "SCardAudit { hContext: %p", (void*)hContext); + WLog_Print(g_Log, g_LogLevel, "SCardAudit { hContext: %p", (void*)hContext); status = g_SCardApi->pfnSCardAudit(hContext, dwEvent); - WLog_Print(g_Log, WLOG_DEBUG, "SCardAudit } status: %s (0x%08" PRIX32 ")", + WLog_Print(g_Log, g_LogLevel, "SCardAudit } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status); return status; @@ -1219,7 +1220,7 @@ static LONG WINAPI Inspect_SCardAudit(SCARDCONTEXT hContext, DWORD dwEvent) * Extended API */ -SCardApiFunctionTable Inspect_SCardApiFunctionTable = { +static const SCardApiFunctionTable Inspect_SCardApiFunctionTable = { 0, /* dwVersion */ 0, /* dwFlags */ @@ -1301,44 +1302,16 @@ SCardApiFunctionTable Inspect_SCardApiFunctionTable = { Inspect_SCardAudit /* SCardAudit */ }; -#ifndef _WIN32 -#define SMARTCARD_INSPECT_FILEPATH "/tmp" -#else -#define SMARTCARD_INSPECT_FILEPATH "C:\\Windows\\Temp" -#endif - static void Inspect_InitLog(void) { - wLogLayout* layout; - wLogAppender* appender; - const char* filepath = SMARTCARD_INSPECT_FILEPATH; - if (g_Log) return; - if (!PathFileExistsA(filepath)) - if (!PathMakePathA(filepath, NULL)) - return; - if (!(g_Log = WLog_Get("WinSCard"))) return; - - WLog_SetLogLevel(g_Log, WLOG_DEBUG); - WLog_SetLogAppenderType(g_Log, WLOG_APPENDER_FILE); - appender = WLog_GetLogAppender(g_Log); - if (!appender) - return; - - WLog_ConfigureAppender(appender, "outputfilename", "WinSCard.txt"); - WLog_ConfigureAppender(appender, "outputfilepath", (void*)filepath); - - layout = WLog_GetLogLayout(g_Log); - WLog_Layout_SetPrefixFormat(g_Log, layout, "[%mn] "); - - WLog_OpenAppender(g_Log); } -PSCardApiFunctionTable Inspect_RegisterSCardApi(PSCardApiFunctionTable pSCardApi) +const SCardApiFunctionTable* Inspect_RegisterSCardApi(const SCardApiFunctionTable* pSCardApi) { g_SCardApi = pSCardApi; diff --git a/winpr/libwinpr/smartcard/smartcard_inspect.h b/winpr/libwinpr/smartcard/smartcard_inspect.h index 52f6e9713..482dd97e0 100644 --- a/winpr/libwinpr/smartcard/smartcard_inspect.h +++ b/winpr/libwinpr/smartcard/smartcard_inspect.h @@ -3,6 +3,8 @@ * Smart Card API * * Copyright 2014 Marc-Andre Moreau + * Copyright 2020 Armin Novak + * Copyright 2020 Thincast Technologies GmbH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +25,6 @@ #include #include -PSCardApiFunctionTable Inspect_RegisterSCardApi(PSCardApiFunctionTable pSCardApi); +const SCardApiFunctionTable* Inspect_RegisterSCardApi(const SCardApiFunctionTable* pSCardApi); #endif /* WINPR_SMARTCARD_INSPECT_PRIVATE_H */ diff --git a/winpr/libwinpr/smartcard/smartcard_pcsc.c b/winpr/libwinpr/smartcard/smartcard_pcsc.c index d2d645d42..3b98d9248 100644 --- a/winpr/libwinpr/smartcard/smartcard_pcsc.c +++ b/winpr/libwinpr/smartcard/smartcard_pcsc.c @@ -3,6 +3,8 @@ * Smart Card API * * Copyright 2014 Marc-Andre Moreau + * Copyright 2020 Armin Novak + * Copyright 2020 Thincast Technologies GmbH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -110,10 +112,84 @@ */ //#define DISABLE_PCSC_SCARD_AUTOALLOCATE +#include "smartcard_pcsc.h" + +#define PCSC_SCARD_PCI_T0 (&g_PCSC_rgSCardT0Pci) +#define PCSC_SCARD_PCI_T1 (&g_PCSC_rgSCardT1Pci) +#define PCSC_SCARD_PCI_RAW (&g_PCSC_rgSCardRawPci) + +typedef PCSC_LONG (*fnPCSCSCardEstablishContext)(PCSC_DWORD dwScope, LPCVOID pvReserved1, + LPCVOID pvReserved2, LPSCARDCONTEXT phContext); +typedef PCSC_LONG (*fnPCSCSCardReleaseContext)(SCARDCONTEXT hContext); +typedef PCSC_LONG (*fnPCSCSCardIsValidContext)(SCARDCONTEXT hContext); +typedef PCSC_LONG (*fnPCSCSCardConnect)(SCARDCONTEXT hContext, LPCSTR szReader, + PCSC_DWORD dwShareMode, PCSC_DWORD dwPreferredProtocols, + LPSCARDHANDLE phCard, PCSC_LPDWORD pdwActiveProtocol); +typedef PCSC_LONG (*fnPCSCSCardReconnect)(SCARDHANDLE hCard, PCSC_DWORD dwShareMode, + PCSC_DWORD dwPreferredProtocols, + PCSC_DWORD dwInitialization, + PCSC_LPDWORD pdwActiveProtocol); +typedef PCSC_LONG (*fnPCSCSCardDisconnect)(SCARDHANDLE hCard, PCSC_DWORD dwDisposition); +typedef PCSC_LONG (*fnPCSCSCardBeginTransaction)(SCARDHANDLE hCard); +typedef PCSC_LONG (*fnPCSCSCardEndTransaction)(SCARDHANDLE hCard, PCSC_DWORD dwDisposition); +typedef PCSC_LONG (*fnPCSCSCardStatus)(SCARDHANDLE hCard, LPSTR mszReaderName, + PCSC_LPDWORD pcchReaderLen, PCSC_LPDWORD pdwState, + PCSC_LPDWORD pdwProtocol, LPBYTE pbAtr, + PCSC_LPDWORD pcbAtrLen); +typedef PCSC_LONG (*fnPCSCSCardGetStatusChange)(SCARDCONTEXT hContext, PCSC_DWORD dwTimeout, + PCSC_SCARD_READERSTATE* rgReaderStates, + PCSC_DWORD cReaders); +typedef PCSC_LONG (*fnPCSCSCardControl)(SCARDHANDLE hCard, PCSC_DWORD dwControlCode, + LPCVOID pbSendBuffer, PCSC_DWORD cbSendLength, + LPVOID pbRecvBuffer, PCSC_DWORD cbRecvLength, + PCSC_LPDWORD lpBytesReturned); +typedef PCSC_LONG (*fnPCSCSCardTransmit)(SCARDHANDLE hCard, const PCSC_SCARD_IO_REQUEST* pioSendPci, + LPCBYTE pbSendBuffer, PCSC_DWORD cbSendLength, + PCSC_SCARD_IO_REQUEST* pioRecvPci, LPBYTE pbRecvBuffer, + PCSC_LPDWORD pcbRecvLength); +typedef PCSC_LONG (*fnPCSCSCardListReaderGroups)(SCARDCONTEXT hContext, LPSTR mszGroups, + PCSC_LPDWORD pcchGroups); +typedef PCSC_LONG (*fnPCSCSCardListReaders)(SCARDCONTEXT hContext, LPCSTR mszGroups, + LPSTR mszReaders, PCSC_LPDWORD pcchReaders); +typedef PCSC_LONG (*fnPCSCSCardFreeMemory)(SCARDCONTEXT hContext, LPCVOID pvMem); +typedef PCSC_LONG (*fnPCSCSCardCancel)(SCARDCONTEXT hContext); +typedef PCSC_LONG (*fnPCSCSCardGetAttrib)(SCARDHANDLE hCard, PCSC_DWORD dwAttrId, LPBYTE pbAttr, + PCSC_LPDWORD pcbAttrLen); +typedef PCSC_LONG (*fnPCSCSCardSetAttrib)(SCARDHANDLE hCard, PCSC_DWORD dwAttrId, LPCBYTE pbAttr, + PCSC_DWORD cbAttrLen); + +struct _PCSCFunctionTable +{ + fnPCSCSCardEstablishContext pfnSCardEstablishContext; + fnPCSCSCardReleaseContext pfnSCardReleaseContext; + fnPCSCSCardIsValidContext pfnSCardIsValidContext; + fnPCSCSCardConnect pfnSCardConnect; + fnPCSCSCardReconnect pfnSCardReconnect; + fnPCSCSCardDisconnect pfnSCardDisconnect; + fnPCSCSCardBeginTransaction pfnSCardBeginTransaction; + fnPCSCSCardEndTransaction pfnSCardEndTransaction; + fnPCSCSCardStatus pfnSCardStatus; + fnPCSCSCardGetStatusChange pfnSCardGetStatusChange; + fnPCSCSCardControl pfnSCardControl; + fnPCSCSCardTransmit pfnSCardTransmit; + fnPCSCSCardListReaderGroups pfnSCardListReaderGroups; + fnPCSCSCardListReaders pfnSCardListReaders; + fnPCSCSCardFreeMemory pfnSCardFreeMemory; + fnPCSCSCardCancel pfnSCardCancel; + fnPCSCSCardGetAttrib pfnSCardGetAttrib; + fnPCSCSCardSetAttrib pfnSCardSetAttrib; +}; +typedef struct _PCSCFunctionTable PCSCFunctionTable; typedef struct _PCSC_SCARDCONTEXT PCSC_SCARDCONTEXT; typedef struct _PCSC_SCARDHANDLE PCSC_SCARDHANDLE; +typedef struct +{ + DWORD len; + BYTE* data; +} PCSC_CACHE_ITEM; + struct _PCSC_SCARDCONTEXT { SCARDHANDLE owner; @@ -121,6 +197,7 @@ struct _PCSC_SCARDCONTEXT SCARDCONTEXT hContext; DWORD dwCardHandleCount; BOOL isTransactionLocked; + wHashTable* cache; }; struct _PCSC_SCARDHANDLE @@ -146,16 +223,16 @@ static wListDictionary* g_CardHandles = NULL; static wListDictionary* g_CardContexts = NULL; static wListDictionary* g_MemoryBlocks = NULL; -char SMARTCARD_PNP_NOTIFICATION_A[] = "\\\\?PnP?\\Notification"; +static const char SMARTCARD_PNP_NOTIFICATION_A[] = "\\\\?PnP?\\Notification"; -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) }; +static const PCSC_SCARD_IO_REQUEST g_PCSC_rgSCardT0Pci = { SCARD_PROTOCOL_T0, + sizeof(PCSC_SCARD_IO_REQUEST) }; +static const PCSC_SCARD_IO_REQUEST g_PCSC_rgSCardT1Pci = { SCARD_PROTOCOL_T1, + sizeof(PCSC_SCARD_IO_REQUEST) }; +static const PCSC_SCARD_IO_REQUEST g_PCSC_rgSCardRawPci = { PCSC_SCARD_PROTOCOL_RAW, + sizeof(PCSC_SCARD_IO_REQUEST) }; -static LONG WINAPI PCSC_SCardFreeMemory_Internal(SCARDCONTEXT hContext, LPCVOID pvMem); +static LONG WINAPI PCSC_SCardFreeMemory_Internal(SCARDCONTEXT hContext, LPVOID pvMem); static LONG WINAPI PCSC_SCardEstablishContext_Internal(DWORD dwScope, LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext); @@ -163,11 +240,11 @@ static LONG WINAPI PCSC_SCardReleaseContext_Internal(SCARDCONTEXT hContext); static LONG PCSC_SCard_LogError(const char* what) { - WLog_DBG(TAG, "Missing function pointer %s=NULL", what); - return SCARD_E_NO_SERVICE; + WLog_WARN(TAG, "Missing function pointer %s=NULL", what); + return SCARD_E_UNSUPPORTED_FEATURE; } -static LONG PCSC_MapErrorCodeToWinSCard(LONG errorCode) +static LONG PCSC_MapErrorCodeToWinSCard(PCSC_LONG errorCode) { /** * pcsc-lite returns SCARD_E_UNEXPECTED when it @@ -177,13 +254,16 @@ static LONG PCSC_MapErrorCodeToWinSCard(LONG errorCode) * define SCARD_E_UNSUPPORTED_FEATURE to 0x8010001F, * when the real value should be 0x80100022. */ - if (errorCode == SCARD_E_UNEXPECTED) - errorCode = SCARD_E_UNSUPPORTED_FEATURE; + if (errorCode != SCARD_S_SUCCESS) + { + if (errorCode == SCARD_E_UNEXPECTED) + errorCode = SCARD_E_UNSUPPORTED_FEATURE; + } - return errorCode; + return (LONG)errorCode; } -static DWORD PCSC_ConvertCardStateToWinSCard(DWORD dwCardState, LONG status) +static DWORD PCSC_ConvertCardStateToWinSCard(DWORD dwCardState, PCSC_LONG status) { /** * pcsc-lite's SCardStatus returns a bit-field, not an enumerated value. @@ -231,7 +311,7 @@ static DWORD PCSC_ConvertCardStateToWinSCard(DWORD dwCardState, LONG status) return SCARD_UNKNOWN; } -static DWORD PCSC_ConvertProtocolsToWinSCard(DWORD dwProtocols) +static DWORD PCSC_ConvertProtocolsToWinSCard(PCSC_DWORD dwProtocols) { /** * pcsc-lite uses a different value for SCARD_PROTOCOL_RAW, @@ -248,7 +328,7 @@ static DWORD PCSC_ConvertProtocolsToWinSCard(DWORD dwProtocols) dwProtocols &= ~PCSC_SCARD_PROTOCOL_T15; } - return dwProtocols; + return (DWORD)dwProtocols; } static DWORD PCSC_ConvertProtocolsFromWinSCard(DWORD dwProtocols) @@ -291,6 +371,14 @@ static PCSC_SCARDCONTEXT* PCSC_GetCardContextData(SCARDCONTEXT hContext) return pContext; } +static void pcsc_cache_item_free(void* ptr) +{ + PCSC_CACHE_ITEM* data = ptr; + if (data) + free(data->data); + free(data); +} + static PCSC_SCARDCONTEXT* PCSC_EstablishCardContext(SCARDCONTEXT hContext) { PCSC_SCARDCONTEXT* pContext; @@ -304,6 +392,12 @@ static PCSC_SCARDCONTEXT* PCSC_EstablishCardContext(SCARDCONTEXT hContext) if (!InitializeCriticalSectionAndSpinCount(&(pContext->lock), 4000)) goto error_spinlock; + pContext->cache = HashTable_New(FALSE); + if (!pContext->cache) + goto errors; + + pContext->cache->keyFree = free; + pContext->cache->valueFree = pcsc_cache_item_free; if (!g_CardContexts) { g_CardContexts = ListDictionary_New(TRUE); @@ -335,6 +429,7 @@ static void PCSC_ReleaseCardContext(SCARDCONTEXT hContext) } DeleteCriticalSection(&(pContext->lock)); + HashTable_Free(pContext->cache); free(pContext); if (!g_CardContexts) @@ -596,21 +691,21 @@ static LONG WINAPI PCSC_SCardEstablishContext_Internal(DWORD dwScope, LPCVOID pv LPSCARDCONTEXT phContext) { WINPR_UNUSED(dwScope); /* SCARD_SCOPE_SYSTEM is the only scope supported by pcsc-lite */ - LONG status = SCARD_S_SUCCESS; + PCSC_LONG status = SCARD_S_SUCCESS; if (!g_PCSC.pfnSCardEstablishContext) return PCSC_SCard_LogError("g_PCSC.pfnSCardEstablishContext"); - status = (LONG)g_PCSC.pfnSCardEstablishContext(SCARD_SCOPE_SYSTEM, pvReserved1, pvReserved2, - phContext); - status = PCSC_MapErrorCodeToWinSCard(status); - return status; + status = + g_PCSC.pfnSCardEstablishContext(SCARD_SCOPE_SYSTEM, pvReserved1, pvReserved2, phContext); + return PCSC_MapErrorCodeToWinSCard(status); } static LONG WINAPI PCSC_SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext) { LONG status; + status = PCSC_SCardEstablishContext_Internal(dwScope, pvReserved1, pvReserved2, phContext); if (status == SCARD_S_SUCCESS) @@ -621,7 +716,7 @@ static LONG WINAPI PCSC_SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1 static LONG WINAPI PCSC_SCardReleaseContext_Internal(SCARDCONTEXT hContext) { - LONG status = SCARD_S_SUCCESS; + PCSC_LONG status = SCARD_S_SUCCESS; if (!g_PCSC.pfnSCardReleaseContext) return PCSC_SCard_LogError("g_PCSC.pfnSCardReleaseContext"); @@ -629,17 +724,17 @@ static LONG WINAPI PCSC_SCardReleaseContext_Internal(SCARDCONTEXT hContext) if (!hContext) { WLog_ERR(TAG, "SCardReleaseContext: null hContext"); - return status; + return PCSC_MapErrorCodeToWinSCard(status); } - status = (LONG)g_PCSC.pfnSCardReleaseContext(hContext); - status = PCSC_MapErrorCodeToWinSCard(status); - return status; + status = g_PCSC.pfnSCardReleaseContext(hContext); + return PCSC_MapErrorCodeToWinSCard(status); } static LONG WINAPI PCSC_SCardReleaseContext(SCARDCONTEXT hContext) { LONG status = SCARD_S_SUCCESS; + status = PCSC_SCardReleaseContext_Internal(hContext); if (status != SCARD_S_SUCCESS) @@ -650,23 +745,26 @@ static LONG WINAPI PCSC_SCardReleaseContext(SCARDCONTEXT hContext) static LONG WINAPI PCSC_SCardIsValidContext(SCARDCONTEXT hContext) { - LONG status = SCARD_S_SUCCESS; + PCSC_LONG status = SCARD_S_SUCCESS; if (!g_PCSC.pfnSCardIsValidContext) return PCSC_SCard_LogError("g_PCSC.pfnSCardIsValidContext"); - status = (LONG)g_PCSC.pfnSCardIsValidContext(hContext); - status = PCSC_MapErrorCodeToWinSCard(status); - return status; + status = g_PCSC.pfnSCardIsValidContext(hContext); + return PCSC_MapErrorCodeToWinSCard(status); } static LONG WINAPI PCSC_SCardListReaderGroups_Internal(SCARDCONTEXT hContext, LPSTR mszGroups, LPDWORD pcchGroups) { - LONG status = SCARD_S_SUCCESS; + PCSC_LONG status = SCARD_S_SUCCESS; BOOL pcchGroupsAlloc = FALSE; - LPSTR* pMszGroups = (LPSTR*)mszGroups; PCSC_DWORD pcsc_cchGroups = 0; + union { + LPSTR lpstr; + LPSTR* lppstr; + } conv; + conv.lpstr = mszGroups; if (!pcchGroups) return SCARD_E_INVALID_PARAMETER; @@ -682,31 +780,30 @@ static LONG WINAPI PCSC_SCardListReaderGroups_Internal(SCARDCONTEXT hContext, LP if (pcchGroupsAlloc && !g_SCardAutoAllocate) { pcsc_cchGroups = 0; - status = (LONG)g_PCSC.pfnSCardListReaderGroups(hContext, NULL, &pcsc_cchGroups); + status = g_PCSC.pfnSCardListReaderGroups(hContext, NULL, &pcsc_cchGroups); if (status == SCARD_S_SUCCESS) { - *pMszGroups = calloc(1, pcsc_cchGroups); + *conv.lppstr = calloc(1, pcsc_cchGroups); - if (!*pMszGroups) + if (!*conv.lppstr) return SCARD_E_NO_MEMORY; - status = (LONG)g_PCSC.pfnSCardListReaderGroups(hContext, *pMszGroups, &pcsc_cchGroups); + status = g_PCSC.pfnSCardListReaderGroups(hContext, *conv.lppstr, &pcsc_cchGroups); if (status != SCARD_S_SUCCESS) - free(*pMszGroups); + free(*conv.lppstr); else - PCSC_AddMemoryBlock(hContext, *pMszGroups); + PCSC_AddMemoryBlock(hContext, *conv.lppstr); } } else { - status = (LONG)g_PCSC.pfnSCardListReaderGroups(hContext, mszGroups, &pcsc_cchGroups); + status = g_PCSC.pfnSCardListReaderGroups(hContext, mszGroups, &pcsc_cchGroups); } - status = PCSC_MapErrorCodeToWinSCard(status); *pcchGroups = (DWORD)pcsc_cchGroups; - return status; + return PCSC_MapErrorCodeToWinSCard(status); } static LONG WINAPI PCSC_SCardListReaderGroupsA(SCARDCONTEXT hContext, LPSTR mszGroups, @@ -734,6 +831,11 @@ static LONG WINAPI PCSC_SCardListReaderGroupsW(SCARDCONTEXT hContext, LPWSTR msz LPSTR mszGroupsA = NULL; LPSTR* pMszGroupsA = &mszGroupsA; LONG status = SCARD_S_SUCCESS; + union { + LPWSTR lpstr; + LPWSTR* lppstr; + } conv; + conv.lpstr = mszGroups; if (!g_PCSC.pfnSCardListReaderGroups) return PCSC_SCard_LogError("g_PCSC.pfnSCardListReaderGroups"); @@ -745,9 +847,11 @@ static LONG WINAPI PCSC_SCardListReaderGroupsW(SCARDCONTEXT hContext, LPWSTR msz if (status == SCARD_S_SUCCESS) { - *pcchGroups = - ConvertToUnicode(CP_UTF8, 0, *pMszGroupsA, *pcchGroups, (WCHAR**)mszGroups, 0); - PCSC_AddMemoryBlock(hContext, mszGroups); + int rc = ConvertToUnicode(CP_UTF8, 0, *pMszGroupsA, (int)*pcchGroups, conv.lppstr, 0); + if (rc < 0) + return SCARD_E_NO_MEMORY; + *pcchGroups = (DWORD)rc; + PCSC_AddMemoryBlock(hContext, conv.lpstr); PCSC_SCardFreeMemory_Internal(hContext, *pMszGroupsA); } @@ -760,10 +864,14 @@ static LONG WINAPI PCSC_SCardListReaderGroupsW(SCARDCONTEXT hContext, LPWSTR msz static LONG WINAPI PCSC_SCardListReaders_Internal(SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders, LPDWORD pcchReaders) { - LONG status = SCARD_S_SUCCESS; + PCSC_LONG status = SCARD_S_SUCCESS; BOOL pcchReadersAlloc = FALSE; - LPSTR* pMszReaders = (LPSTR*)mszReaders; PCSC_DWORD pcsc_cchReaders = 0; + union { + LPSTR lpstr; + LPSTR* lppstr; + } conv; + conv.lpstr = mszReaders; if (!pcchReaders) return SCARD_E_INVALID_PARAMETER; @@ -781,33 +889,31 @@ static LONG WINAPI PCSC_SCardListReaders_Internal(SCARDCONTEXT hContext, LPCSTR if (pcchReadersAlloc && !g_SCardAutoAllocate) { pcsc_cchReaders = 0; - status = (LONG)g_PCSC.pfnSCardListReaders(hContext, mszGroups, NULL, &pcsc_cchReaders); + status = g_PCSC.pfnSCardListReaders(hContext, mszGroups, NULL, &pcsc_cchReaders); if (status == SCARD_S_SUCCESS) { - *pMszReaders = calloc(1, pcsc_cchReaders); + *conv.lppstr = calloc(1, pcsc_cchReaders); - if (!*pMszReaders) + if (!*conv.lppstr) return SCARD_E_NO_MEMORY; - status = (LONG)g_PCSC.pfnSCardListReaders(hContext, mszGroups, *pMszReaders, - &pcsc_cchReaders); + status = + g_PCSC.pfnSCardListReaders(hContext, mszGroups, *conv.lppstr, &pcsc_cchReaders); if (status != SCARD_S_SUCCESS) - free(*pMszReaders); + free(*conv.lppstr); else - PCSC_AddMemoryBlock(hContext, *pMszReaders); + PCSC_AddMemoryBlock(hContext, *conv.lppstr); } } else { - status = - (LONG)g_PCSC.pfnSCardListReaders(hContext, mszGroups, mszReaders, &pcsc_cchReaders); + status = g_PCSC.pfnSCardListReaders(hContext, mszGroups, mszReaders, &pcsc_cchReaders); } - status = PCSC_MapErrorCodeToWinSCard(status); *pcchReaders = (DWORD)pcsc_cchReaders; - return status; + return PCSC_MapErrorCodeToWinSCard(status); } static LONG WINAPI PCSC_SCardListReadersA(SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders, @@ -853,6 +959,11 @@ static LONG WINAPI PCSC_SCardListReadersW(SCARDCONTEXT hContext, LPCWSTR mszGrou LPSTR* pMszReadersA = &mszReadersA; LONG status = SCARD_S_SUCCESS; BOOL nullCardContext = FALSE; + union { + LPWSTR lpstr; + LPWSTR* lppstr; + } conv; + conv.lpstr = mszReaders; if (!g_PCSC.pfnSCardListReaders) return PCSC_SCard_LogError("g_PCSC.pfnSCardListReaders"); @@ -879,9 +990,11 @@ static LONG WINAPI PCSC_SCardListReadersW(SCARDCONTEXT hContext, LPCWSTR mszGrou if (status == SCARD_S_SUCCESS) { - *pcchReaders = - ConvertToUnicode(CP_UTF8, 0, *pMszReadersA, *pcchReaders, (WCHAR**)mszReaders, 0); - PCSC_AddMemoryBlock(hContext, mszReaders); + int rc = ConvertToUnicode(CP_UTF8, 0, *pMszReadersA, (int)*pcchReaders, conv.lppstr, 0); + if (rc < 0) + return SCARD_E_NO_MEMORY; + *pcchReaders = (DWORD)rc; + PCSC_AddMemoryBlock(hContext, conv.lpstr); PCSC_SCardFreeMemory_Internal(hContext, *pMszReadersA); } @@ -902,118 +1015,184 @@ static LONG WINAPI PCSC_SCardListCardsA(SCARDCONTEXT hContext, LPCBYTE pbAtr, LPCGUID rgquidInterfaces, DWORD cguidInterfaceCount, CHAR* mszCards, LPDWORD pcchCards) { - return 0; + WINPR_UNUSED(hContext); + WINPR_UNUSED(pbAtr); + WINPR_UNUSED(rgquidInterfaces); + WINPR_UNUSED(cguidInterfaceCount); + WINPR_UNUSED(mszCards); + WINPR_UNUSED(pcchCards); + return SCARD_E_UNSUPPORTED_FEATURE; } static LONG WINAPI PCSC_SCardListCardsW(SCARDCONTEXT hContext, LPCBYTE pbAtr, LPCGUID rgquidInterfaces, DWORD cguidInterfaceCount, WCHAR* mszCards, LPDWORD pcchCards) { - return 0; + WINPR_UNUSED(hContext); + WINPR_UNUSED(pbAtr); + WINPR_UNUSED(rgquidInterfaces); + WINPR_UNUSED(cguidInterfaceCount); + WINPR_UNUSED(mszCards); + WINPR_UNUSED(pcchCards); + return SCARD_E_UNSUPPORTED_FEATURE; } static LONG WINAPI PCSC_SCardListInterfacesA(SCARDCONTEXT hContext, LPCSTR szCard, LPGUID pguidInterfaces, LPDWORD pcguidInterfaces) { - return 0; + WINPR_UNUSED(hContext); + WINPR_UNUSED(szCard); + WINPR_UNUSED(pguidInterfaces); + WINPR_UNUSED(pcguidInterfaces); + return SCARD_E_UNSUPPORTED_FEATURE; } static LONG WINAPI PCSC_SCardListInterfacesW(SCARDCONTEXT hContext, LPCWSTR szCard, LPGUID pguidInterfaces, LPDWORD pcguidInterfaces) { - return 0; + WINPR_UNUSED(hContext); + WINPR_UNUSED(szCard); + WINPR_UNUSED(pguidInterfaces); + WINPR_UNUSED(pcguidInterfaces); + return SCARD_E_UNSUPPORTED_FEATURE; } static LONG WINAPI PCSC_SCardGetProviderIdA(SCARDCONTEXT hContext, LPCSTR szCard, LPGUID pguidProviderId) { - return 0; + WINPR_UNUSED(hContext); + WINPR_UNUSED(szCard); + WINPR_UNUSED(pguidProviderId); + return SCARD_E_UNSUPPORTED_FEATURE; } static LONG WINAPI PCSC_SCardGetProviderIdW(SCARDCONTEXT hContext, LPCWSTR szCard, LPGUID pguidProviderId) { - return 0; + WINPR_UNUSED(hContext); + WINPR_UNUSED(szCard); + WINPR_UNUSED(pguidProviderId); + return SCARD_E_UNSUPPORTED_FEATURE; } static LONG WINAPI PCSC_SCardGetCardTypeProviderNameA(SCARDCONTEXT hContext, LPCSTR szCardName, DWORD dwProviderId, CHAR* szProvider, LPDWORD pcchProvider) { - return 0; + WINPR_UNUSED(hContext); + WINPR_UNUSED(szCardName); + WINPR_UNUSED(dwProviderId); + WINPR_UNUSED(szProvider); + WINPR_UNUSED(pcchProvider); + return SCARD_E_UNSUPPORTED_FEATURE; } static LONG WINAPI PCSC_SCardGetCardTypeProviderNameW(SCARDCONTEXT hContext, LPCWSTR szCardName, DWORD dwProviderId, WCHAR* szProvider, LPDWORD pcchProvider) { - return 0; + WINPR_UNUSED(hContext); + WINPR_UNUSED(szCardName); + WINPR_UNUSED(dwProviderId); + WINPR_UNUSED(szProvider); + WINPR_UNUSED(pcchProvider); + return SCARD_E_UNSUPPORTED_FEATURE; } static LONG WINAPI PCSC_SCardIntroduceReaderGroupA(SCARDCONTEXT hContext, LPCSTR szGroupName) { - return 0; + WINPR_UNUSED(hContext); + WINPR_UNUSED(szGroupName); + return SCARD_E_UNSUPPORTED_FEATURE; } static LONG WINAPI PCSC_SCardIntroduceReaderGroupW(SCARDCONTEXT hContext, LPCWSTR szGroupName) { - return 0; + WINPR_UNUSED(hContext); + WINPR_UNUSED(szGroupName); + return SCARD_E_UNSUPPORTED_FEATURE; } static LONG WINAPI PCSC_SCardForgetReaderGroupA(SCARDCONTEXT hContext, LPCSTR szGroupName) { - return 0; + WINPR_UNUSED(hContext); + WINPR_UNUSED(szGroupName); + return SCARD_E_UNSUPPORTED_FEATURE; } static LONG WINAPI PCSC_SCardForgetReaderGroupW(SCARDCONTEXT hContext, LPCWSTR szGroupName) { - return 0; + WINPR_UNUSED(hContext); + WINPR_UNUSED(szGroupName); + return SCARD_E_UNSUPPORTED_FEATURE; } static LONG WINAPI PCSC_SCardIntroduceReaderA(SCARDCONTEXT hContext, LPCSTR szReaderName, LPCSTR szDeviceName) { - return 0; + WINPR_UNUSED(hContext); + WINPR_UNUSED(szReaderName); + WINPR_UNUSED(szDeviceName); + return SCARD_E_UNSUPPORTED_FEATURE; } static LONG WINAPI PCSC_SCardIntroduceReaderW(SCARDCONTEXT hContext, LPCWSTR szReaderName, LPCWSTR szDeviceName) { - return 0; + WINPR_UNUSED(hContext); + WINPR_UNUSED(szReaderName); + WINPR_UNUSED(szDeviceName); + return SCARD_E_UNSUPPORTED_FEATURE; } static LONG WINAPI PCSC_SCardForgetReaderA(SCARDCONTEXT hContext, LPCSTR szReaderName) { - return 0; + WINPR_UNUSED(hContext); + WINPR_UNUSED(szReaderName); + return SCARD_E_UNSUPPORTED_FEATURE; } static LONG WINAPI PCSC_SCardForgetReaderW(SCARDCONTEXT hContext, LPCWSTR szReaderName) { - return 0; + WINPR_UNUSED(hContext); + WINPR_UNUSED(szReaderName); + return SCARD_E_UNSUPPORTED_FEATURE; } static LONG WINAPI PCSC_SCardAddReaderToGroupA(SCARDCONTEXT hContext, LPCSTR szReaderName, LPCSTR szGroupName) { - return 0; + WINPR_UNUSED(hContext); + WINPR_UNUSED(szReaderName); + WINPR_UNUSED(szGroupName); + return SCARD_E_UNSUPPORTED_FEATURE; } static LONG WINAPI PCSC_SCardAddReaderToGroupW(SCARDCONTEXT hContext, LPCWSTR szReaderName, LPCWSTR szGroupName) { - return 0; + WINPR_UNUSED(hContext); + WINPR_UNUSED(szReaderName); + WINPR_UNUSED(szGroupName); + return SCARD_E_UNSUPPORTED_FEATURE; } static LONG WINAPI PCSC_SCardRemoveReaderFromGroupA(SCARDCONTEXT hContext, LPCSTR szReaderName, LPCSTR szGroupName) { - return 0; + WINPR_UNUSED(hContext); + WINPR_UNUSED(szReaderName); + WINPR_UNUSED(szGroupName); + return SCARD_E_UNSUPPORTED_FEATURE; } static LONG WINAPI PCSC_SCardRemoveReaderFromGroupW(SCARDCONTEXT hContext, LPCWSTR szReaderName, LPCWSTR szGroupName) { - return 0; + WINPR_UNUSED(hContext); + WINPR_UNUSED(szReaderName); + WINPR_UNUSED(szGroupName); + return SCARD_E_UNSUPPORTED_FEATURE; } static LONG WINAPI PCSC_SCardIntroduceCardTypeA(SCARDCONTEXT hContext, LPCSTR szCardName, @@ -1021,7 +1200,15 @@ static LONG WINAPI PCSC_SCardIntroduceCardTypeA(SCARDCONTEXT hContext, LPCSTR sz LPCGUID rgguidInterfaces, DWORD dwInterfaceCount, LPCBYTE pbAtr, LPCBYTE pbAtrMask, DWORD cbAtrLen) { - return 0; + WINPR_UNUSED(hContext); + WINPR_UNUSED(szCardName); + WINPR_UNUSED(pguidPrimaryProvider); + WINPR_UNUSED(rgguidInterfaces); + WINPR_UNUSED(dwInterfaceCount); + WINPR_UNUSED(pbAtr); + WINPR_UNUSED(pbAtrMask); + WINPR_UNUSED(cbAtrLen); + return SCARD_E_UNSUPPORTED_FEATURE; } static LONG WINAPI PCSC_SCardIntroduceCardTypeW(SCARDCONTEXT hContext, LPCWSTR szCardName, @@ -1029,36 +1216,56 @@ static LONG WINAPI PCSC_SCardIntroduceCardTypeW(SCARDCONTEXT hContext, LPCWSTR s LPCGUID rgguidInterfaces, DWORD dwInterfaceCount, LPCBYTE pbAtr, LPCBYTE pbAtrMask, DWORD cbAtrLen) { - return 0; + WINPR_UNUSED(hContext); + WINPR_UNUSED(szCardName); + WINPR_UNUSED(pguidPrimaryProvider); + WINPR_UNUSED(rgguidInterfaces); + WINPR_UNUSED(dwInterfaceCount); + WINPR_UNUSED(pbAtr); + WINPR_UNUSED(pbAtrMask); + WINPR_UNUSED(cbAtrLen); + return SCARD_E_UNSUPPORTED_FEATURE; } static LONG WINAPI PCSC_SCardSetCardTypeProviderNameA(SCARDCONTEXT hContext, LPCSTR szCardName, DWORD dwProviderId, LPCSTR szProvider) { - return 0; + WINPR_UNUSED(hContext); + WINPR_UNUSED(szCardName); + WINPR_UNUSED(dwProviderId); + WINPR_UNUSED(szProvider); + return SCARD_E_UNSUPPORTED_FEATURE; } static LONG WINAPI PCSC_SCardSetCardTypeProviderNameW(SCARDCONTEXT hContext, LPCWSTR szCardName, DWORD dwProviderId, LPCWSTR szProvider) { - return 0; + WINPR_UNUSED(hContext); + WINPR_UNUSED(szCardName); + WINPR_UNUSED(dwProviderId); + WINPR_UNUSED(szProvider); + return SCARD_E_UNSUPPORTED_FEATURE; } static LONG WINAPI PCSC_SCardForgetCardTypeA(SCARDCONTEXT hContext, LPCSTR szCardName) { - return 0; + WINPR_UNUSED(hContext); + WINPR_UNUSED(szCardName); + return SCARD_E_UNSUPPORTED_FEATURE; } static LONG WINAPI PCSC_SCardForgetCardTypeW(SCARDCONTEXT hContext, LPCWSTR szCardName) { - return 0; + WINPR_UNUSED(hContext); + WINPR_UNUSED(szCardName); + return SCARD_E_UNSUPPORTED_FEATURE; } -static LONG WINAPI PCSC_SCardFreeMemory_Internal(SCARDCONTEXT hContext, LPCVOID pvMem) +static LONG WINAPI PCSC_SCardFreeMemory_Internal(SCARDCONTEXT hContext, LPVOID pvMem) { - LONG status = SCARD_S_SUCCESS; + PCSC_LONG status = SCARD_S_SUCCESS; - if (PCSC_RemoveMemoryBlock(hContext, (void*)pvMem)) + if (PCSC_RemoveMemoryBlock(hContext, pvMem)) { free((void*)pvMem); status = SCARD_S_SUCCESS; @@ -1067,15 +1274,14 @@ static LONG WINAPI PCSC_SCardFreeMemory_Internal(SCARDCONTEXT hContext, LPCVOID { if (g_PCSC.pfnSCardFreeMemory) { - status = (LONG)g_PCSC.pfnSCardFreeMemory(hContext, pvMem); - status = PCSC_MapErrorCodeToWinSCard(status); + status = g_PCSC.pfnSCardFreeMemory(hContext, pvMem); } } - return status; + return PCSC_MapErrorCodeToWinSCard(status); } -static LONG WINAPI PCSC_SCardFreeMemory(SCARDCONTEXT hContext, LPCVOID pvMem) +static LONG WINAPI PCSC_SCardFreeMemory(SCARDCONTEXT hContext, LPVOID pvMem) { LONG status = SCARD_S_SUCCESS; @@ -1100,6 +1306,7 @@ static HANDLE WINAPI PCSC_SCardAccessStartedEvent(void) { LONG status = 0; SCARDCONTEXT hContext = 0; + status = PCSC_SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext); if (status != SCARD_S_SUCCESS) @@ -1143,27 +1350,45 @@ static void WINAPI PCSC_SCardReleaseStartedEvent(void) static LONG WINAPI PCSC_SCardLocateCardsA(SCARDCONTEXT hContext, LPCSTR mszCards, LPSCARD_READERSTATEA rgReaderStates, DWORD cReaders) { - return 0; + WINPR_UNUSED(hContext); + WINPR_UNUSED(mszCards); + WINPR_UNUSED(rgReaderStates); + WINPR_UNUSED(cReaders); + return SCARD_E_UNSUPPORTED_FEATURE; } static LONG WINAPI PCSC_SCardLocateCardsW(SCARDCONTEXT hContext, LPCWSTR mszCards, LPSCARD_READERSTATEW rgReaderStates, DWORD cReaders) { - return 0; + WINPR_UNUSED(hContext); + WINPR_UNUSED(mszCards); + WINPR_UNUSED(rgReaderStates); + WINPR_UNUSED(cReaders); + return SCARD_E_UNSUPPORTED_FEATURE; } static LONG WINAPI PCSC_SCardLocateCardsByATRA(SCARDCONTEXT hContext, LPSCARD_ATRMASK rgAtrMasks, DWORD cAtrs, LPSCARD_READERSTATEA rgReaderStates, DWORD cReaders) { - return 0; + WINPR_UNUSED(hContext); + WINPR_UNUSED(rgAtrMasks); + WINPR_UNUSED(cAtrs); + WINPR_UNUSED(rgReaderStates); + WINPR_UNUSED(cReaders); + return SCARD_E_UNSUPPORTED_FEATURE; } static LONG WINAPI PCSC_SCardLocateCardsByATRW(SCARDCONTEXT hContext, LPSCARD_ATRMASK rgAtrMasks, DWORD cAtrs, LPSCARD_READERSTATEW rgReaderStates, DWORD cReaders) { - return 0; + WINPR_UNUSED(hContext); + WINPR_UNUSED(rgAtrMasks); + WINPR_UNUSED(cAtrs); + WINPR_UNUSED(rgReaderStates); + WINPR_UNUSED(cReaders); + return SCARD_E_UNSUPPORTED_FEATURE; } static LONG WINAPI PCSC_SCardGetStatusChange_Internal(SCARDCONTEXT hContext, DWORD dwTimeout, @@ -1171,10 +1396,10 @@ static LONG WINAPI PCSC_SCardGetStatusChange_Internal(SCARDCONTEXT hContext, DWO DWORD cReaders) { PCSC_DWORD i, j; - int* map; + INT64* map; PCSC_DWORD cMappedReaders; PCSC_SCARD_READERSTATE* states; - LONG status = SCARD_S_SUCCESS; + PCSC_LONG status = SCARD_S_SUCCESS; PCSC_DWORD pcsc_dwTimeout = (PCSC_DWORD)dwTimeout; PCSC_DWORD pcsc_cReaders = (PCSC_DWORD)cReaders; @@ -1199,7 +1424,7 @@ static LONG WINAPI PCSC_SCardGetStatusChange_Internal(SCARDCONTEXT hContext, DWO * To work around this apparent lack of "\\\\?PnP?\\Notification" support, * we have to filter rgReaderStates to exclude the special PnP reader name. */ - map = (int*)calloc(pcsc_cReaders, sizeof(int)); + map = (INT64*)calloc(pcsc_cReaders, sizeof(INT64)); if (!map) return SCARD_E_NO_MEMORY; @@ -1223,7 +1448,7 @@ static LONG WINAPI PCSC_SCardGetStatusChange_Internal(SCARDCONTEXT hContext, DWO } } - map[i] = j; + map[i] = (INT64)j; states[j].szReader = rgReaderStates[i].szReader; states[j].dwCurrentState = rgReaderStates[i].dwCurrentState; states[j].pvUserData = rgReaderStates[i].pvUserData; @@ -1237,9 +1462,7 @@ static LONG WINAPI PCSC_SCardGetStatusChange_Internal(SCARDCONTEXT hContext, DWO if (cMappedReaders > 0) { - status = - (LONG)g_PCSC.pfnSCardGetStatusChange(hContext, pcsc_dwTimeout, states, cMappedReaders); - status = PCSC_MapErrorCodeToWinSCard(status); + status = g_PCSC.pfnSCardGetStatusChange(hContext, pcsc_dwTimeout, states, cMappedReaders); } else { @@ -1251,16 +1474,16 @@ static LONG WINAPI PCSC_SCardGetStatusChange_Internal(SCARDCONTEXT hContext, DWO if (map[i] < 0) continue; /* unmapped */ - j = map[i]; - rgReaderStates[i].dwCurrentState = states[j].dwCurrentState; - rgReaderStates[i].cbAtr = states[j].cbAtr; + j = (PCSC_DWORD)map[i]; + rgReaderStates[i].dwCurrentState = (DWORD)states[j].dwCurrentState; + rgReaderStates[i].cbAtr = (DWORD)states[j].cbAtr; CopyMemory(&(rgReaderStates[i].rgbAtr), &(states[j].rgbAtr), PCSC_MAX_ATR_SIZE); - rgReaderStates[i].dwEventState = states[j].dwEventState; + rgReaderStates[i].dwEventState = (DWORD)states[j].dwEventState; } free(map); free(states); - return status; + return PCSC_MapErrorCodeToWinSCard(status); } static LONG WINAPI PCSC_SCardGetStatusChangeA(SCARDCONTEXT hContext, DWORD dwTimeout, @@ -1334,14 +1557,13 @@ static LONG WINAPI PCSC_SCardGetStatusChangeW(SCARDCONTEXT hContext, DWORD dwTim static LONG WINAPI PCSC_SCardCancel(SCARDCONTEXT hContext) { - LONG status = SCARD_S_SUCCESS; + PCSC_LONG status = SCARD_S_SUCCESS; if (!g_PCSC.pfnSCardCancel) return PCSC_SCard_LogError("g_PCSC.pfnSCardCancel"); - status = (LONG)g_PCSC.pfnSCardCancel(hContext); - status = PCSC_MapErrorCodeToWinSCard(status); - return status; + status = g_PCSC.pfnSCardCancel(hContext); + return PCSC_MapErrorCodeToWinSCard(status); } static LONG WINAPI PCSC_SCardConnect_Internal(SCARDCONTEXT hContext, LPCSTR szReader, @@ -1349,8 +1571,8 @@ static LONG WINAPI PCSC_SCardConnect_Internal(SCARDCONTEXT hContext, LPCSTR szRe LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol) { BOOL shared; - char* szReaderPCSC; - LONG status = SCARD_S_SUCCESS; + const char* szReaderPCSC; + PCSC_LONG status = SCARD_S_SUCCESS; PCSC_SCARDHANDLE* pCard = NULL; PCSC_DWORD pcsc_dwShareMode = (PCSC_DWORD)dwShareMode; PCSC_DWORD pcsc_dwPreferredProtocols = 0; @@ -1361,7 +1583,7 @@ static LONG WINAPI PCSC_SCardConnect_Internal(SCARDCONTEXT hContext, LPCSTR szRe shared = (dwShareMode == SCARD_SHARE_DIRECT) ? TRUE : FALSE; PCSC_WaitForCardAccess(hContext, 0, shared); - szReaderPCSC = (char*)szReader; + szReaderPCSC = szReader; /** * As stated here : @@ -1376,10 +1598,8 @@ static LONG WINAPI PCSC_SCardConnect_Internal(SCARDCONTEXT hContext, LPCSTR szRe pcsc_dwPreferredProtocols = (PCSC_DWORD)PCSC_ConvertProtocolsFromWinSCard(dwPreferredProtocols); - status = - (LONG)g_PCSC.pfnSCardConnect(hContext, szReaderPCSC, pcsc_dwShareMode, - pcsc_dwPreferredProtocols, phCard, &pcsc_dwActiveProtocol); - status = PCSC_MapErrorCodeToWinSCard(status); + status = g_PCSC.pfnSCardConnect(hContext, szReaderPCSC, pcsc_dwShareMode, + pcsc_dwPreferredProtocols, phCard, &pcsc_dwActiveProtocol); if (status == SCARD_S_SUCCESS) { @@ -1389,7 +1609,7 @@ static LONG WINAPI PCSC_SCardConnect_Internal(SCARDCONTEXT hContext, LPCSTR szRe PCSC_WaitForCardAccess(hContext, pCard->hSharedContext, shared); } - return status; + return PCSC_MapErrorCodeToWinSCard(status); } static LONG WINAPI PCSC_SCardConnectA(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode, @@ -1438,7 +1658,7 @@ static LONG WINAPI PCSC_SCardReconnect(SCARDHANDLE hCard, DWORD dwShareMode, LPDWORD pdwActiveProtocol) { BOOL shared; - LONG status = SCARD_S_SUCCESS; + PCSC_LONG status = SCARD_S_SUCCESS; PCSC_DWORD pcsc_dwShareMode = (PCSC_DWORD)dwShareMode; PCSC_DWORD pcsc_dwPreferredProtocols = 0; PCSC_DWORD pcsc_dwInitialization = (PCSC_DWORD)dwInitialization; @@ -1450,23 +1670,22 @@ static LONG WINAPI PCSC_SCardReconnect(SCARDHANDLE hCard, DWORD dwShareMode, shared = (dwShareMode == SCARD_SHARE_DIRECT) ? TRUE : FALSE; 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); - status = PCSC_MapErrorCodeToWinSCard(status); + status = g_PCSC.pfnSCardReconnect(hCard, pcsc_dwShareMode, pcsc_dwPreferredProtocols, + pcsc_dwInitialization, &pcsc_dwActiveProtocol); + *pdwActiveProtocol = PCSC_ConvertProtocolsToWinSCard((DWORD)pcsc_dwActiveProtocol); - return status; + return PCSC_MapErrorCodeToWinSCard(status); } static LONG WINAPI PCSC_SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition) { - LONG status = SCARD_S_SUCCESS; + PCSC_LONG status = SCARD_S_SUCCESS; PCSC_DWORD pcsc_dwDisposition = (PCSC_DWORD)dwDisposition; if (!g_PCSC.pfnSCardDisconnect) return PCSC_SCard_LogError("g_PCSC.pfnSCardDisconnect"); - status = (LONG)g_PCSC.pfnSCardDisconnect(hCard, pcsc_dwDisposition); - status = PCSC_MapErrorCodeToWinSCard(status); + status = g_PCSC.pfnSCardDisconnect(hCard, pcsc_dwDisposition); if (status == SCARD_S_SUCCESS) { @@ -1474,12 +1693,12 @@ static LONG WINAPI PCSC_SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition) } PCSC_ReleaseCardAccess(0, hCard); - return status; + return PCSC_MapErrorCodeToWinSCard(status); } static LONG WINAPI PCSC_SCardBeginTransaction(SCARDHANDLE hCard) { - LONG status = SCARD_S_SUCCESS; + PCSC_LONG status = SCARD_S_SUCCESS; PCSC_SCARDHANDLE* pCard = NULL; PCSC_SCARDCONTEXT* pContext = NULL; @@ -1499,15 +1718,15 @@ static LONG WINAPI PCSC_SCardBeginTransaction(SCARDHANDLE hCard) if (pContext->isTransactionLocked) return SCARD_S_SUCCESS; /* disable nested transactions */ - status = (LONG)g_PCSC.pfnSCardBeginTransaction(hCard); - status = PCSC_MapErrorCodeToWinSCard(status); + status = g_PCSC.pfnSCardBeginTransaction(hCard); + pContext->isTransactionLocked = TRUE; - return status; + return PCSC_MapErrorCodeToWinSCard(status); } static LONG WINAPI PCSC_SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition) { - LONG status = SCARD_S_SUCCESS; + PCSC_LONG status = SCARD_S_SUCCESS; PCSC_SCARDHANDLE* pCard = NULL; PCSC_SCARDCONTEXT* pContext = NULL; PCSC_DWORD pcsc_dwDisposition = (PCSC_DWORD)dwDisposition; @@ -1530,14 +1749,15 @@ static LONG WINAPI PCSC_SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDispositi if (!pContext->isTransactionLocked) return SCARD_S_SUCCESS; /* disable nested transactions */ - status = (LONG)g_PCSC.pfnSCardEndTransaction(hCard, pcsc_dwDisposition); - status = PCSC_MapErrorCodeToWinSCard(status); + status = g_PCSC.pfnSCardEndTransaction(hCard, pcsc_dwDisposition); + pContext->isTransactionLocked = FALSE; - return status; + return PCSC_MapErrorCodeToWinSCard(status); } static LONG WINAPI PCSC_SCardCancelTransaction(SCARDHANDLE hCard) { + WINPR_UNUSED(hCard); return SCARD_S_SUCCESS; } @@ -1547,7 +1767,7 @@ static LONG WINAPI PCSC_SCardState(SCARDHANDLE hCard, LPDWORD pdwState, LPDWORD PCSC_DWORD cchReaderLen; SCARDCONTEXT hContext = 0; LPSTR mszReaderNames = NULL; - LONG status = SCARD_S_SUCCESS; + PCSC_LONG status = SCARD_S_SUCCESS; PCSC_SCARDHANDLE* pCard = NULL; PCSC_DWORD pcsc_dwState = 0; PCSC_DWORD pcsc_dwProtocol = 0; @@ -1568,9 +1788,8 @@ static LONG WINAPI PCSC_SCardState(SCARDHANDLE hCard, LPDWORD pdwState, LPDWORD return SCARD_E_INVALID_VALUE; cchReaderLen = SCARD_AUTOALLOCATE; - status = (LONG)g_PCSC.pfnSCardStatus(hCard, (LPSTR)&mszReaderNames, &cchReaderLen, - &pcsc_dwState, &pcsc_dwProtocol, pbAtr, &pcsc_cbAtrLen); - status = PCSC_MapErrorCodeToWinSCard(status); + status = g_PCSC.pfnSCardStatus(hCard, (LPSTR)&mszReaderNames, &cchReaderLen, &pcsc_dwState, + &pcsc_dwProtocol, pbAtr, &pcsc_cbAtrLen); if (mszReaderNames) PCSC_SCardFreeMemory_Internal(hContext, mszReaderNames); @@ -1578,7 +1797,7 @@ static LONG WINAPI PCSC_SCardState(SCARDHANDLE hCard, LPDWORD pdwState, LPDWORD *pdwState = (DWORD)pcsc_dwState; *pdwProtocol = PCSC_ConvertProtocolsToWinSCard((DWORD)pcsc_dwProtocol); *pcbAtrLen = (DWORD)pcsc_cbAtrLen; - return status; + return PCSC_MapErrorCodeToWinSCard(status); } /* @@ -1592,7 +1811,7 @@ static LONG WINAPI PCSC_SCardStatus_Internal(SCARDHANDLE hCard, LPSTR mszReaderN { PCSC_SCARDHANDLE* pCard = NULL; SCARDCONTEXT hContext; - LONG status; + PCSC_LONG status; PCSC_DWORD pcsc_cchReaderLen = 0; PCSC_DWORD pcsc_cbAtrLen = 0; PCSC_DWORD pcsc_dwState = 0; @@ -1618,8 +1837,8 @@ static LONG WINAPI PCSC_SCardStatus_Internal(SCARDHANDLE hCard, LPSTR mszReaderN if (!hContext) return SCARD_E_INVALID_VALUE; - status = (LONG)g_PCSC.pfnSCardStatus(hCard, NULL, &pcsc_cchReaderLen, NULL, NULL, NULL, - &pcsc_cbAtrLen); + status = + g_PCSC.pfnSCardStatus(hCard, NULL, &pcsc_cchReaderLen, NULL, NULL, NULL, &pcsc_cbAtrLen); if (status != STATUS_SUCCESS) return PCSC_MapErrorCodeToWinSCard(status); @@ -1684,42 +1903,54 @@ static LONG WINAPI PCSC_SCardStatus_Internal(SCARDHANDLE hCard, LPSTR mszReaderN atr = tATR; } - status = (LONG)g_PCSC.pfnSCardStatus(hCard, readerNames, &pcsc_cchReaderLen, &pcsc_dwState, - &pcsc_dwProtocol, atr, &pcsc_cbAtrLen); + status = g_PCSC.pfnSCardStatus(hCard, readerNames, &pcsc_cchReaderLen, &pcsc_dwState, + &pcsc_dwProtocol, atr, &pcsc_cbAtrLen); if (status != STATUS_SUCCESS) goto out_fail; if (tATR) { + union { + BYTE* pb; + BYTE** ppb; + } conv; + conv.pb = pbAtr; PCSC_AddMemoryBlock(hContext, tATR); - *(LPBYTE*)pbAtr = tATR; + *conv.ppb = tATR; } if (tReader) { + union { + CHAR* pc; + CHAR** ppc; + WCHAR* pw; + WCHAR** ppw; + } conv, dst; + dst.pc = mszReaderNames; + if (unicode) { - LPSTR mszReaderNamesW = NULL; - int pcsc_cchReaderLenW = 0; - pcsc_cchReaderLenW = - ConvertToUnicode(CP_UTF8, 0, tReader, *pcchReaderLen, (WCHAR**)&mszReaderNamesW, 0); + int pcsc_cchReaderLenW = + ConvertToUnicode(CP_UTF8, 0, tReader, (int)*pcchReaderLen, &conv.pw, 0); - if (pcsc_cchReaderLenW <= 0 || mszReaderNamesW == NULL) + if ((pcsc_cchReaderLenW <= 0) || (conv.pw == NULL)) { status = ERROR_NOT_ENOUGH_MEMORY; goto out_fail; } - readerNames = mszReaderNamesW; free(tReader); - PCSC_AddMemoryBlock(hContext, mszReaderNamesW); - *(LPSTR*)mszReaderNames = mszReaderNamesW; + conv.pw[pcsc_cchReaderLen - 1] = L'\0'; + PCSC_AddMemoryBlock(hContext, conv.pw); + *dst.ppw = conv.pw; } else { + tReader[pcsc_cchReaderLen - 1] = '\0'; PCSC_AddMemoryBlock(hContext, tReader); - *(LPSTR*)mszReaderNames = tReader; + *dst.ppc = tReader; } } @@ -1735,36 +1966,20 @@ static LONG WINAPI PCSC_SCardStatus_Internal(SCARDHANDLE hCard, LPSTR mszReaderN *pcbAtrLen = (DWORD)pcsc_cbAtrLen; if (pcchReaderLen) - { - if (unicode) - *pcchReaderLen = (pcsc_cchReaderLen + 1) * 2; - else - *pcchReaderLen = pcsc_cchReaderLen + 1; - } + *pcchReaderLen = pcsc_cchReaderLen + 1u; - /* Make sure the last byte is set */ - if (readerNames) - { - if (unicode) - { - readerNames[pcsc_cchReaderLen * 2] = '\0'; - readerNames[pcsc_cchReaderLen * 2 + 1] = '\0'; - } - else - readerNames[pcsc_cchReaderLen] = '\0'; - } - - return status; + return (LONG)status; out_fail: free(tReader); free(tATR); - return status; + return (LONG)status; } static LONG WINAPI PCSC_SCardStatusA(SCARDHANDLE hCard, LPSTR mszReaderNames, LPDWORD pcchReaderLen, LPDWORD pdwState, LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen) { + return PCSC_SCardStatus_Internal(hCard, mszReaderNames, pcchReaderLen, pdwState, pdwProtocol, pbAtr, pcbAtrLen, FALSE); } @@ -1773,6 +1988,7 @@ static LONG WINAPI PCSC_SCardStatusW(SCARDHANDLE hCard, LPWSTR mszReaderNames, LPDWORD pcchReaderLen, LPDWORD pdwState, LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen) { + return PCSC_SCardStatus_Internal(hCard, (LPSTR)mszReaderNames, pcchReaderLen, pdwState, pdwProtocol, pbAtr, pcbAtrLen, TRUE); } @@ -1782,15 +1998,25 @@ static LONG WINAPI PCSC_SCardTransmit(SCARDHANDLE hCard, LPCSCARD_IO_REQUEST pio LPSCARD_IO_REQUEST pioRecvPci, LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength) { - LONG status = SCARD_S_SUCCESS; + PCSC_LONG status = SCARD_S_SUCCESS; PCSC_SCARDHANDLE* pCard = NULL; PCSC_DWORD cbExtraBytes = 0; BYTE* pbExtraBytes = NULL; BYTE* pcsc_pbExtraBytes = NULL; - PCSC_SCARD_IO_REQUEST* pcsc_pioSendPci = NULL; - PCSC_SCARD_IO_REQUEST* pcsc_pioRecvPci = NULL; PCSC_DWORD pcsc_cbSendLength = (PCSC_DWORD)cbSendLength; PCSC_DWORD pcsc_cbRecvLength = 0; + union { + const PCSC_SCARD_IO_REQUEST* pcs; + PCSC_SCARD_IO_REQUEST* ps; + LPSCARD_IO_REQUEST lps; + LPCSCARD_IO_REQUEST lpcs; + BYTE* pb; + } sendPci, recvPci, inRecvPci, inSendPci; + + sendPci.ps = NULL; + recvPci.ps = NULL; + inRecvPci.lps = pioRecvPci; + inSendPci.lpcs = pioSendPci; if (!g_PCSC.pfnSCardTransmit) return PCSC_SCard_LogError("g_PCSC.pfnSCardTransmit"); @@ -1810,7 +2036,7 @@ static LONG WINAPI PCSC_SCardTransmit(SCARDHANDLE hCard, LPCSCARD_IO_REQUEST pio pcsc_cbRecvLength = (PCSC_DWORD)*pcbRecvLength; - if (!pioSendPci) + if (!inSendPci.lpcs) { PCSC_DWORD dwState = 0; PCSC_DWORD cbAtrLen = 0; @@ -1820,82 +2046,82 @@ static LONG WINAPI PCSC_SCardTransmit(SCARDHANDLE hCard, LPCSCARD_IO_REQUEST pio * pcsc-lite cannot have a null pioSendPci parameter, unlike WinSCard. * Query the current protocol and use default SCARD_IO_REQUEST for it. */ - status = (LONG)g_PCSC.pfnSCardStatus(hCard, NULL, &cchReaderLen, &dwState, &dwProtocol, - NULL, &cbAtrLen); + status = g_PCSC.pfnSCardStatus(hCard, NULL, &cchReaderLen, &dwState, &dwProtocol, NULL, + &cbAtrLen); if (status == SCARD_S_SUCCESS) { if (dwProtocol == SCARD_PROTOCOL_T0) - pcsc_pioSendPci = (PCSC_SCARD_IO_REQUEST*)PCSC_SCARD_PCI_T0; + sendPci.pcs = PCSC_SCARD_PCI_T0; else if (dwProtocol == SCARD_PROTOCOL_T1) - pcsc_pioSendPci = (PCSC_SCARD_IO_REQUEST*)PCSC_SCARD_PCI_T1; + sendPci.pcs = PCSC_SCARD_PCI_T1; else if (dwProtocol == PCSC_SCARD_PROTOCOL_RAW) - pcsc_pioSendPci = (PCSC_SCARD_IO_REQUEST*)PCSC_SCARD_PCI_RAW; + sendPci.pcs = PCSC_SCARD_PCI_RAW; } } else { - cbExtraBytes = pioSendPci->cbPciLength - sizeof(SCARD_IO_REQUEST); - pcsc_pioSendPci = - (PCSC_SCARD_IO_REQUEST*)malloc(sizeof(PCSC_SCARD_IO_REQUEST) + cbExtraBytes); + cbExtraBytes = inSendPci.lpcs->cbPciLength - sizeof(SCARD_IO_REQUEST); + sendPci.ps = (PCSC_SCARD_IO_REQUEST*)malloc(sizeof(PCSC_SCARD_IO_REQUEST) + cbExtraBytes); - if (!pcsc_pioSendPci) + if (!sendPci.ps) return SCARD_E_NO_MEMORY; - pcsc_pioSendPci->dwProtocol = (PCSC_DWORD)pioSendPci->dwProtocol; - pcsc_pioSendPci->cbPciLength = sizeof(PCSC_SCARD_IO_REQUEST) + cbExtraBytes; - pbExtraBytes = &((BYTE*)pioSendPci)[sizeof(SCARD_IO_REQUEST)]; - pcsc_pbExtraBytes = &((BYTE*)pcsc_pioSendPci)[sizeof(PCSC_SCARD_IO_REQUEST)]; + sendPci.ps->dwProtocol = (PCSC_DWORD)inSendPci.lpcs->dwProtocol; + sendPci.ps->cbPciLength = sizeof(PCSC_SCARD_IO_REQUEST) + cbExtraBytes; + pbExtraBytes = &(inSendPci.pb)[sizeof(SCARD_IO_REQUEST)]; + pcsc_pbExtraBytes = &(sendPci.pb)[sizeof(PCSC_SCARD_IO_REQUEST)]; CopyMemory(pcsc_pbExtraBytes, pbExtraBytes, cbExtraBytes); } - if (pioRecvPci) + if (inRecvPci.lps) { - cbExtraBytes = pioRecvPci->cbPciLength - sizeof(SCARD_IO_REQUEST); - pcsc_pioRecvPci = - (PCSC_SCARD_IO_REQUEST*)malloc(sizeof(PCSC_SCARD_IO_REQUEST) + cbExtraBytes); + cbExtraBytes = inRecvPci.lps->cbPciLength - sizeof(SCARD_IO_REQUEST); + recvPci.ps = (PCSC_SCARD_IO_REQUEST*)malloc(sizeof(PCSC_SCARD_IO_REQUEST) + cbExtraBytes); - if (!pcsc_pioRecvPci) + if (!recvPci.ps) { - if (pioSendPci) - free(pcsc_pioSendPci); + if (inSendPci.lpcs) + free(sendPci.ps); return SCARD_E_NO_MEMORY; } - pcsc_pioRecvPci->dwProtocol = (PCSC_DWORD)pioRecvPci->dwProtocol; - pcsc_pioRecvPci->cbPciLength = sizeof(PCSC_SCARD_IO_REQUEST) + cbExtraBytes; - pbExtraBytes = &((BYTE*)pioRecvPci)[sizeof(SCARD_IO_REQUEST)]; - pcsc_pbExtraBytes = &((BYTE*)pcsc_pioRecvPci)[sizeof(PCSC_SCARD_IO_REQUEST)]; + recvPci.ps->dwProtocol = (PCSC_DWORD)inRecvPci.lps->dwProtocol; + recvPci.ps->cbPciLength = sizeof(PCSC_SCARD_IO_REQUEST) + cbExtraBytes; + pbExtraBytes = &(inRecvPci.pb)[sizeof(SCARD_IO_REQUEST)]; + pcsc_pbExtraBytes = &(recvPci.pb)[sizeof(PCSC_SCARD_IO_REQUEST)]; CopyMemory(pcsc_pbExtraBytes, pbExtraBytes, cbExtraBytes); } - status = (LONG)g_PCSC.pfnSCardTransmit(hCard, pcsc_pioSendPci, pbSendBuffer, pcsc_cbSendLength, - pcsc_pioRecvPci, pbRecvBuffer, &pcsc_cbRecvLength); - status = PCSC_MapErrorCodeToWinSCard(status); + status = g_PCSC.pfnSCardTransmit(hCard, sendPci.ps, pbSendBuffer, pcsc_cbSendLength, recvPci.ps, + pbRecvBuffer, &pcsc_cbRecvLength); + *pcbRecvLength = (DWORD)pcsc_cbRecvLength; - if (pioSendPci) - free(pcsc_pioSendPci); /* pcsc_pioSendPci is dynamically allocated only when pioSendPci is + if (inSendPci.lpcs) + free(sendPci.ps); /* pcsc_pioSendPci is dynamically allocated only when pioSendPci is non null */ - if (pioRecvPci) + if (inRecvPci.lps) { - cbExtraBytes = pioRecvPci->cbPciLength - sizeof(SCARD_IO_REQUEST); - pbExtraBytes = &((BYTE*)pioRecvPci)[sizeof(SCARD_IO_REQUEST)]; - pcsc_pbExtraBytes = &((BYTE*)pcsc_pioRecvPci)[sizeof(PCSC_SCARD_IO_REQUEST)]; + cbExtraBytes = inRecvPci.lps->cbPciLength - sizeof(SCARD_IO_REQUEST); + pbExtraBytes = &(inRecvPci.pb)[sizeof(SCARD_IO_REQUEST)]; + pcsc_pbExtraBytes = &(recvPci.pb)[sizeof(PCSC_SCARD_IO_REQUEST)]; CopyMemory(pbExtraBytes, pcsc_pbExtraBytes, cbExtraBytes); /* copy extra bytes */ - free(pcsc_pioRecvPci); /* pcsc_pioRecvPci is dynamically allocated only when pioRecvPci is + free(recvPci.ps); /* pcsc_pioRecvPci is dynamically allocated only when pioRecvPci is non null */ } - return status; + return PCSC_MapErrorCodeToWinSCard(status); + ; } static LONG WINAPI PCSC_SCardGetTransmitCount(SCARDHANDLE hCard, LPDWORD pcTransmitCount) { WINPR_UNUSED(pcTransmitCount); PCSC_SCARDHANDLE* pCard = NULL; + pCard = PCSC_GetCardHandleData(hCard); if (!pCard) @@ -1914,7 +2140,7 @@ static LONG WINAPI PCSC_SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPC DWORD IoCtlAccess = 0; DWORD IoCtlDeviceType = 0; BOOL getFeatureRequest = FALSE; - LONG status = SCARD_S_SUCCESS; + PCSC_LONG status = SCARD_S_SUCCESS; PCSC_SCARDHANDLE* pCard = NULL; PCSC_DWORD pcsc_dwControlCode = 0; PCSC_DWORD pcsc_cbInBufferSize = (PCSC_DWORD)cbInBufferSize; @@ -1952,10 +2178,9 @@ static LONG WINAPI PCSC_SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPC dwControlCode = PCSC_SCARD_CTL_CODE(IoCtlFunction); pcsc_dwControlCode = (PCSC_DWORD)dwControlCode; - status = - (LONG)g_PCSC.pfnSCardControl(hCard, pcsc_dwControlCode, lpInBuffer, pcsc_cbInBufferSize, - lpOutBuffer, pcsc_cbOutBufferSize, &pcsc_BytesReturned); - status = PCSC_MapErrorCodeToWinSCard(status); + status = g_PCSC.pfnSCardControl(hCard, pcsc_dwControlCode, lpInBuffer, pcsc_cbInBufferSize, + lpOutBuffer, pcsc_cbOutBufferSize, &pcsc_BytesReturned); + *lpBytesReturned = (DWORD)pcsc_BytesReturned; if (getFeatureRequest) @@ -1976,7 +2201,8 @@ static LONG WINAPI PCSC_SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPC } } - return status; + return PCSC_MapErrorCodeToWinSCard(status); + ; } static LONG WINAPI PCSC_SCardGetAttrib_Internal(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr, @@ -1984,12 +2210,15 @@ static LONG WINAPI PCSC_SCardGetAttrib_Internal(SCARDHANDLE hCard, DWORD dwAttrI { SCARDCONTEXT hContext = 0; BOOL pcbAttrLenAlloc = FALSE; - LPBYTE* pPbAttr = (LPBYTE*)pbAttr; - LONG status = SCARD_S_SUCCESS; + PCSC_LONG status = SCARD_S_SUCCESS; PCSC_SCARDHANDLE* pCard = NULL; PCSC_DWORD pcsc_dwAttrId = (PCSC_DWORD)dwAttrId; PCSC_DWORD pcsc_cbAttrLen = 0; - + union { + BYTE* pb; + BYTE** ppb; + } conv; + conv.pb = pbAttr; if (!g_PCSC.pfnSCardGetAttrib) return PCSC_SCard_LogError("g_PCSC.pfnSCardGetAttrib"); @@ -2015,35 +2244,31 @@ static LONG WINAPI PCSC_SCardGetAttrib_Internal(SCARDHANDLE hCard, DWORD dwAttrI if (pcbAttrLenAlloc && !g_SCardAutoAllocate) { pcsc_cbAttrLen = 0; - status = (LONG)g_PCSC.pfnSCardGetAttrib(hCard, pcsc_dwAttrId, NULL, &pcsc_cbAttrLen); + status = g_PCSC.pfnSCardGetAttrib(hCard, pcsc_dwAttrId, NULL, &pcsc_cbAttrLen); if (status == SCARD_S_SUCCESS) { - *pPbAttr = (BYTE*)calloc(1, pcsc_cbAttrLen); + *conv.ppb = (BYTE*)calloc(1, pcsc_cbAttrLen); - if (!*pPbAttr) + if (!*conv.ppb) return SCARD_E_NO_MEMORY; - status = - (LONG)g_PCSC.pfnSCardGetAttrib(hCard, pcsc_dwAttrId, *pPbAttr, &pcsc_cbAttrLen); + status = g_PCSC.pfnSCardGetAttrib(hCard, pcsc_dwAttrId, *conv.ppb, &pcsc_cbAttrLen); if (status != SCARD_S_SUCCESS) - free(*pPbAttr); + free(*conv.ppb); else - PCSC_AddMemoryBlock(hContext, *pPbAttr); + PCSC_AddMemoryBlock(hContext, *conv.ppb); } } else { - status = (LONG)g_PCSC.pfnSCardGetAttrib(hCard, pcsc_dwAttrId, pbAttr, &pcsc_cbAttrLen); + status = g_PCSC.pfnSCardGetAttrib(hCard, pcsc_dwAttrId, pbAttr, &pcsc_cbAttrLen); } - status = PCSC_MapErrorCodeToWinSCard(status); - if (status == SCARD_S_SUCCESS) *pcbAttrLen = (DWORD)pcsc_cbAttrLen; - - return status; + return PCSC_MapErrorCodeToWinSCard(status); } static LONG WINAPI PCSC_SCardGetAttrib_FriendlyName(SCARDHANDLE hCard, DWORD dwAttrId, @@ -2058,7 +2283,12 @@ static LONG WINAPI PCSC_SCardGetAttrib_FriendlyName(SCARDHANDLE hCard, DWORD dwA char* friendlyNameA = NULL; WCHAR* friendlyNameW = NULL; LONG status = SCARD_S_SUCCESS; - LPBYTE* pPbAttr = (LPBYTE*)pbAttr; + union { + WCHAR** ppw; + BYTE* pb; + BYTE** ppb; + } conv; + conv.pb = pbAttr; hContext = PCSC_GetCardContextFromHandle(hCard); if (!hContext) @@ -2079,7 +2309,7 @@ static LONG WINAPI PCSC_SCardGetAttrib_FriendlyName(SCARDHANDLE hCard, DWORD dwA if (status != SCARD_S_SUCCESS) return status; - ConvertFromUnicode(CP_UTF8, 0, (WCHAR*)pbAttrW, *pcbAttrLen, (char**)&pbAttrA, 0, NULL, + ConvertFromUnicode(CP_UTF8, 0, (WCHAR*)pbAttrW, (int)*pcbAttrLen, (char**)&pbAttrA, 0, NULL, NULL); namePCSC = pbAttrA; PCSC_SCardFreeMemory_Internal(hContext, pbAttrW); @@ -2101,20 +2331,20 @@ static LONG WINAPI PCSC_SCardGetAttrib_FriendlyName(SCARDHANDLE hCard, DWORD dwA if (dwAttrId == SCARD_ATTR_DEVICE_FRIENDLY_NAME_W) { /* length here includes null terminator */ - length = ConvertToUnicode(CP_UTF8, 0, (char*)friendlyNameA, -1, &friendlyNameW, 0); + int rc = ConvertToUnicode(CP_UTF8, 0, (char*)friendlyNameA, -1, &friendlyNameW, 0); free(friendlyNameA); - - if (!friendlyNameW) + if ((rc < 0) || (!friendlyNameW)) { free(namePCSC); return SCARD_E_NO_MEMORY; } + length = (size_t)rc; if (cbAttrLen == SCARD_AUTOALLOCATE) { - *pPbAttr = (BYTE*)friendlyNameW; + *conv.ppw = friendlyNameW; *pcbAttrLen = length * 2; - PCSC_AddMemoryBlock(hContext, *pPbAttr); + PCSC_AddMemoryBlock(hContext, *conv.ppb); } else { @@ -2136,9 +2366,9 @@ static LONG WINAPI PCSC_SCardGetAttrib_FriendlyName(SCARDHANDLE hCard, DWORD dwA { if (cbAttrLen == SCARD_AUTOALLOCATE) { - *pPbAttr = (BYTE*)friendlyNameA; + *conv.ppb = (BYTE*)friendlyNameA; *pcbAttrLen = length; - PCSC_AddMemoryBlock(hContext, *pPbAttr); + PCSC_AddMemoryBlock(hContext, *conv.ppb); } else { @@ -2168,13 +2398,19 @@ static LONG WINAPI PCSC_SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE SCARDCONTEXT hContext; BOOL pcbAttrLenAlloc = FALSE; LONG status = SCARD_S_SUCCESS; - LPBYTE* pPbAttr = (LPBYTE*)pbAttr; + union { + BYTE* pb; + BYTE** ppb; + } conv; + + conv.pb = pbAttr; + cbAttrLen = *pcbAttrLen; if (*pcbAttrLen == SCARD_AUTOALLOCATE) { pcbAttrLenAlloc = TRUE; - *pPbAttr = NULL; + *conv.ppb = NULL; } else { @@ -2212,7 +2448,7 @@ static LONG WINAPI PCSC_SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE */ if (pcbAttrLenAlloc) - vendorName = (char*)*pPbAttr; + vendorName = (char*)*conv.ppb; else vendorName = (char*)pbAttr; @@ -2224,6 +2460,7 @@ static LONG WINAPI PCSC_SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE } else { + if (dwAttrId == SCARD_ATTR_CURRENT_PROTOCOL_TYPE) { if (!pcbAttrLenAlloc) @@ -2237,12 +2474,17 @@ static LONG WINAPI PCSC_SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE if (status == SCARD_S_SUCCESS) { - LPDWORD pdwProtocol = (LPDWORD)pbAttr; + union { + BYTE* pb; + LPDWORD pd; + } conv; + + conv.pb = pbAttr; if (cbAttrLen < sizeof(DWORD)) return SCARD_E_INSUFFICIENT_BUFFER; - *pdwProtocol = PCSC_ConvertProtocolsToWinSCard(dwProtocol); + *conv.pd = PCSC_ConvertProtocolsToWinSCard(dwProtocol); *pcbAttrLen = sizeof(DWORD); } } @@ -2251,14 +2493,20 @@ static LONG WINAPI PCSC_SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE { if (!pcbAttrLenAlloc) { - UINT16 channelType = 0x20; /* USB */ - UINT16 channelNumber = 0; + UINT32 channelType = 0x20; /* USB */ + UINT32 channelNumber = 0; + union { + BYTE* pb; + BYTE** ppb; + DWORD* ppd; + } conv; + conv.pb = pbAttr; if (cbAttrLen < sizeof(DWORD)) return SCARD_E_INSUFFICIENT_BUFFER; status = SCARD_S_SUCCESS; - *((DWORD*)pbAttr) = (channelType << 16) | channelNumber; + *conv.ppd = (channelType << 16u) | channelNumber; *pcbAttrLen = sizeof(DWORD); } } @@ -2330,7 +2578,7 @@ static LONG WINAPI PCSC_SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE static LONG WINAPI PCSC_SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPCBYTE pbAttr, DWORD cbAttrLen) { - LONG status = SCARD_S_SUCCESS; + PCSC_LONG status = SCARD_S_SUCCESS; PCSC_SCARDHANDLE* pCard = NULL; PCSC_DWORD pcsc_dwAttrId = (PCSC_DWORD)dwAttrId; PCSC_DWORD pcsc_cbAttrLen = (PCSC_DWORD)cbAttrLen; @@ -2344,107 +2592,298 @@ static LONG WINAPI PCSC_SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPCBYT return SCARD_E_INVALID_VALUE; PCSC_WaitForCardAccess(0, hCard, pCard->shared); - status = (LONG)g_PCSC.pfnSCardSetAttrib(hCard, pcsc_dwAttrId, pbAttr, pcsc_cbAttrLen); - status = PCSC_MapErrorCodeToWinSCard(status); - return status; + status = g_PCSC.pfnSCardSetAttrib(hCard, pcsc_dwAttrId, pbAttr, pcsc_cbAttrLen); + return PCSC_MapErrorCodeToWinSCard(status); } static LONG WINAPI PCSC_SCardUIDlgSelectCardA(LPOPENCARDNAMEA_EX pDlgStruc) { - return 0; + WINPR_UNUSED(pDlgStruc); + + return SCARD_E_UNSUPPORTED_FEATURE; } static LONG WINAPI PCSC_SCardUIDlgSelectCardW(LPOPENCARDNAMEW_EX pDlgStruc) { - return 0; + WINPR_UNUSED(pDlgStruc); + return SCARD_E_UNSUPPORTED_FEATURE; } static LONG WINAPI PCSC_GetOpenCardNameA(LPOPENCARDNAMEA pDlgStruc) { - return 0; + WINPR_UNUSED(pDlgStruc); + return SCARD_E_UNSUPPORTED_FEATURE; } static LONG WINAPI PCSC_GetOpenCardNameW(LPOPENCARDNAMEW pDlgStruc) { - return 0; + WINPR_UNUSED(pDlgStruc); + return SCARD_E_UNSUPPORTED_FEATURE; } static LONG WINAPI PCSC_SCardDlgExtendedError(void) { - return 0; + + return SCARD_E_UNSUPPORTED_FEATURE; +} + +static char* card_id_and_name_a(const UUID* CardIdentifier, LPCSTR LookupName) +{ + size_t len = strlen(LookupName) + 34; + char* id = malloc(len); + if (!id) + return NULL; + + snprintf(id, len, "%08X%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X\\%s", CardIdentifier->Data1, + CardIdentifier->Data2, CardIdentifier->Data3, CardIdentifier->Data4[0], + CardIdentifier->Data4[1], CardIdentifier->Data4[2], CardIdentifier->Data4[3], + CardIdentifier->Data4[4], CardIdentifier->Data4[5], CardIdentifier->Data4[6], + CardIdentifier->Data4[7], LookupName); + return id; +} + +static char* card_id_and_name_w(const UUID* CardIdentifier, LPCWSTR LookupName) +{ + char* res; + char* tmp = NULL; + + ConvertFromUnicode(CP_UTF8, 0, LookupName, -1, &tmp, 0, NULL, NULL); + res = card_id_and_name_a(CardIdentifier, tmp); + free(tmp); + return res; } static LONG WINAPI PCSC_SCardReadCacheA(SCARDCONTEXT hContext, UUID* CardIdentifier, DWORD FreshnessCounter, LPSTR LookupName, PBYTE Data, DWORD* DataLen) { - return 0; + PCSC_CACHE_ITEM* data; + PCSC_SCARDCONTEXT* ctx = PCSC_GetCardContextData(hContext); + char* id = card_id_and_name_a(CardIdentifier, LookupName); + WINPR_UNUSED(FreshnessCounter); + + data = HashTable_GetItemValue(ctx->cache, id); + free(id); + if (!data) + { + *DataLen = 0; + return SCARD_S_SUCCESS; + } + + if (*DataLen == SCARD_AUTOALLOCATE) + { + BYTE* mem; + union { + BYTE* pb; + BYTE** ppb; + } conv; + + conv.pb = Data; + mem = calloc(1, data->len); + if (!mem) + return SCARD_E_NO_MEMORY; + + if (!PCSC_AddMemoryBlock(hContext, mem)) + { + free(mem); + return SCARD_E_NO_MEMORY; + } + + memcpy(mem, data->data, data->len); + *conv.ppb = mem; + } + else + memcpy(Data, data->data, data->len); + *DataLen = data->len; + return SCARD_S_SUCCESS; } static LONG WINAPI PCSC_SCardReadCacheW(SCARDCONTEXT hContext, UUID* CardIdentifier, DWORD FreshnessCounter, LPWSTR LookupName, PBYTE Data, DWORD* DataLen) { - return 0; + PCSC_CACHE_ITEM* data; + PCSC_SCARDCONTEXT* ctx = PCSC_GetCardContextData(hContext); + char* id = card_id_and_name_w(CardIdentifier, LookupName); + WINPR_UNUSED(FreshnessCounter); + + data = HashTable_GetItemValue(ctx->cache, id); + free(id); + + if (!data) + { + *DataLen = 0; + return SCARD_S_SUCCESS; + } + + if (*DataLen == SCARD_AUTOALLOCATE) + { + BYTE* mem; + union { + BYTE* pb; + BYTE** ppb; + } conv; + + conv.pb = Data; + mem = calloc(1, data->len); + if (!mem) + return SCARD_E_NO_MEMORY; + + if (!PCSC_AddMemoryBlock(hContext, mem)) + { + free(mem); + return SCARD_E_NO_MEMORY; + } + + memcpy(mem, data->data, data->len); + *conv.ppb = mem; + } + else + memcpy(Data, data->data, data->len); + *DataLen = data->len; + return SCARD_S_SUCCESS; } static LONG WINAPI PCSC_SCardWriteCacheA(SCARDCONTEXT hContext, UUID* CardIdentifier, DWORD FreshnessCounter, LPSTR LookupName, PBYTE Data, DWORD DataLen) { - return 0; + PCSC_CACHE_ITEM* data; + PCSC_SCARDCONTEXT* ctx = PCSC_GetCardContextData(hContext); + char* id = card_id_and_name_a(CardIdentifier, LookupName); + + WINPR_UNUSED(FreshnessCounter); + + if (!id) + return SCARD_E_NO_MEMORY; + + data = malloc(sizeof(PCSC_CACHE_ITEM)); + if (!data) + { + free(id); + return SCARD_E_NO_MEMORY; + } + data->data = malloc(DataLen); + if (!data->data) + { + free(id); + free(data); + return SCARD_E_NO_MEMORY; + } + data->len = DataLen; + memcpy(data->data, Data, data->len); + + HashTable_Remove(ctx->cache, id); + HashTable_Add(ctx->cache, id, data); + + return SCARD_S_SUCCESS; } static LONG WINAPI PCSC_SCardWriteCacheW(SCARDCONTEXT hContext, UUID* CardIdentifier, DWORD FreshnessCounter, LPWSTR LookupName, PBYTE Data, DWORD DataLen) { - return 0; + PCSC_CACHE_ITEM* data; + PCSC_SCARDCONTEXT* ctx = PCSC_GetCardContextData(hContext); + char* id = card_id_and_name_w(CardIdentifier, LookupName); + + WINPR_UNUSED(FreshnessCounter); + + if (!id) + return SCARD_E_NO_MEMORY; + + data = malloc(sizeof(PCSC_CACHE_ITEM)); + if (!data) + { + free(id); + return SCARD_E_NO_MEMORY; + } + data->data = malloc(DataLen); + if (!data->data) + { + free(id); + free(data); + return SCARD_E_NO_MEMORY; + } + data->len = DataLen; + memcpy(data->data, Data, data->len); + + HashTable_Remove(ctx->cache, id); + HashTable_Add(ctx->cache, id, data); + + return SCARD_S_SUCCESS; } static LONG WINAPI PCSC_SCardGetReaderIconA(SCARDCONTEXT hContext, LPCSTR szReaderName, LPBYTE pbIcon, LPDWORD pcbIcon) { - return 0; + WINPR_UNUSED(hContext); + WINPR_UNUSED(szReaderName); + WINPR_UNUSED(pbIcon); + WINPR_UNUSED(pcbIcon); + return SCARD_E_UNSUPPORTED_FEATURE; } static LONG WINAPI PCSC_SCardGetReaderIconW(SCARDCONTEXT hContext, LPCWSTR szReaderName, LPBYTE pbIcon, LPDWORD pcbIcon) { - return 0; + WINPR_UNUSED(hContext); + WINPR_UNUSED(szReaderName); + WINPR_UNUSED(pbIcon); + WINPR_UNUSED(pcbIcon); + return SCARD_E_UNSUPPORTED_FEATURE; } static LONG WINAPI PCSC_SCardGetDeviceTypeIdA(SCARDCONTEXT hContext, LPCSTR szReaderName, LPDWORD pdwDeviceTypeId) { - return 0; + WINPR_UNUSED(hContext); + WINPR_UNUSED(szReaderName); + WINPR_UNUSED(pdwDeviceTypeId); + return SCARD_E_UNSUPPORTED_FEATURE; } static LONG WINAPI PCSC_SCardGetDeviceTypeIdW(SCARDCONTEXT hContext, LPCWSTR szReaderName, LPDWORD pdwDeviceTypeId) { - return 0; + WINPR_UNUSED(hContext); + WINPR_UNUSED(szReaderName); + if (pdwDeviceTypeId) + *pdwDeviceTypeId = 0; + return SCARD_E_UNSUPPORTED_FEATURE; } static LONG WINAPI PCSC_SCardGetReaderDeviceInstanceIdA(SCARDCONTEXT hContext, LPCSTR szReaderName, LPSTR szDeviceInstanceId, LPDWORD pcchDeviceInstanceId) { - return 0; + WINPR_UNUSED(hContext); + WINPR_UNUSED(szReaderName); + WINPR_UNUSED(szDeviceInstanceId); + WINPR_UNUSED(pcchDeviceInstanceId); + return SCARD_E_UNSUPPORTED_FEATURE; } static LONG WINAPI PCSC_SCardGetReaderDeviceInstanceIdW(SCARDCONTEXT hContext, LPCWSTR szReaderName, LPWSTR szDeviceInstanceId, LPDWORD pcchDeviceInstanceId) { - return 0; + WINPR_UNUSED(hContext); + WINPR_UNUSED(szReaderName); + WINPR_UNUSED(szDeviceInstanceId); + WINPR_UNUSED(pcchDeviceInstanceId); + return SCARD_E_UNSUPPORTED_FEATURE; } static LONG WINAPI PCSC_SCardListReadersWithDeviceInstanceIdA(SCARDCONTEXT hContext, LPCSTR szDeviceInstanceId, LPSTR mszReaders, LPDWORD pcchReaders) { - return 0; + WINPR_UNUSED(hContext); + WINPR_UNUSED(szDeviceInstanceId); + WINPR_UNUSED(mszReaders); + WINPR_UNUSED(pcchReaders); + return SCARD_E_UNSUPPORTED_FEATURE; } static LONG WINAPI PCSC_SCardListReadersWithDeviceInstanceIdW(SCARDCONTEXT hContext, @@ -2452,12 +2891,19 @@ static LONG WINAPI PCSC_SCardListReadersWithDeviceInstanceIdW(SCARDCONTEXT hCont LPWSTR mszReaders, LPDWORD pcchReaders) { - return 0; + WINPR_UNUSED(hContext); + WINPR_UNUSED(szDeviceInstanceId); + WINPR_UNUSED(mszReaders); + WINPR_UNUSED(pcchReaders); + return SCARD_E_UNSUPPORTED_FEATURE; } static LONG WINAPI PCSC_SCardAudit(SCARDCONTEXT hContext, DWORD dwEvent) { - return 0; + + WINPR_UNUSED(hContext); + WINPR_UNUSED(dwEvent); + return SCARD_E_UNSUPPORTED_FEATURE; } #ifdef __MACOSX__ @@ -2589,7 +3035,7 @@ fail: } #endif -SCardApiFunctionTable PCSC_SCardApiFunctionTable = { +static const SCardApiFunctionTable PCSC_SCardApiFunctionTable = { 0, /* dwVersion */ 0, /* dwFlags */ @@ -2671,7 +3117,7 @@ SCardApiFunctionTable PCSC_SCardApiFunctionTable = { PCSC_SCardAudit /* SCardAudit */ }; -PSCardApiFunctionTable PCSC_GetSCardApiFunctionTable(void) +const SCardApiFunctionTable* PCSC_GetSCardApiFunctionTable(void) { return &PCSC_SCardApiFunctionTable; } @@ -2698,35 +3144,46 @@ int PCSC_InitializeSCardApi(void) if (!g_PCSCModule) return -1; - g_PCSC.pfnSCardEstablishContext = (void*)GetProcAddress(g_PCSCModule, "SCardEstablishContext"); - g_PCSC.pfnSCardReleaseContext = (void*)GetProcAddress(g_PCSCModule, "SCardReleaseContext"); - g_PCSC.pfnSCardIsValidContext = (void*)GetProcAddress(g_PCSCModule, "SCardIsValidContext"); - g_PCSC.pfnSCardConnect = (void*)GetProcAddress(g_PCSCModule, "SCardConnect"); - g_PCSC.pfnSCardReconnect = (void*)GetProcAddress(g_PCSCModule, "SCardReconnect"); - g_PCSC.pfnSCardDisconnect = (void*)GetProcAddress(g_PCSCModule, "SCardDisconnect"); - g_PCSC.pfnSCardBeginTransaction = (void*)GetProcAddress(g_PCSCModule, "SCardBeginTransaction"); - g_PCSC.pfnSCardEndTransaction = (void*)GetProcAddress(g_PCSCModule, "SCardEndTransaction"); - g_PCSC.pfnSCardStatus = (void*)GetProcAddress(g_PCSCModule, "SCardStatus"); - g_PCSC.pfnSCardGetStatusChange = (void*)GetProcAddress(g_PCSCModule, "SCardGetStatusChange"); + g_PCSC.pfnSCardEstablishContext = + (fnPCSCSCardEstablishContext)GetProcAddress(g_PCSCModule, "SCardEstablishContext"); + g_PCSC.pfnSCardReleaseContext = + (fnPCSCSCardReleaseContext)GetProcAddress(g_PCSCModule, "SCardReleaseContext"); + g_PCSC.pfnSCardIsValidContext = + (fnPCSCSCardIsValidContext)GetProcAddress(g_PCSCModule, "SCardIsValidContext"); + g_PCSC.pfnSCardConnect = (fnPCSCSCardConnect)GetProcAddress(g_PCSCModule, "SCardConnect"); + g_PCSC.pfnSCardReconnect = (fnPCSCSCardReconnect)GetProcAddress(g_PCSCModule, "SCardReconnect"); + g_PCSC.pfnSCardDisconnect = + (fnPCSCSCardDisconnect)GetProcAddress(g_PCSCModule, "SCardDisconnect"); + g_PCSC.pfnSCardBeginTransaction = + (fnPCSCSCardBeginTransaction)GetProcAddress(g_PCSCModule, "SCardBeginTransaction"); + g_PCSC.pfnSCardEndTransaction = + (fnPCSCSCardEndTransaction)GetProcAddress(g_PCSCModule, "SCardEndTransaction"); + g_PCSC.pfnSCardStatus = (fnPCSCSCardStatus)GetProcAddress(g_PCSCModule, "SCardStatus"); + g_PCSC.pfnSCardGetStatusChange = + (fnPCSCSCardGetStatusChange)GetProcAddress(g_PCSCModule, "SCardGetStatusChange"); #ifdef __MACOSX__ if (OSXVersion >= 0x10050600) - g_PCSC.pfnSCardControl = (void*)GetProcAddress(g_PCSCModule, "SCardControl132"); + g_PCSC.pfnSCardControl = + (fnPCSCSCardControl)GetProcAddress(g_PCSCModule, "SCardControl132"); else - g_PCSC.pfnSCardControl = (void*)GetProcAddress(g_PCSCModule, "SCardControl"); + g_PCSC.pfnSCardControl = (fnPCSCSCardControl)GetProcAddress(g_PCSCModule, "SCardControl"); #else - g_PCSC.pfnSCardControl = (void*)GetProcAddress(g_PCSCModule, "SCardControl"); + g_PCSC.pfnSCardControl = (fnPCSCSCardControl)GetProcAddress(g_PCSCModule, "SCardControl"); #endif - g_PCSC.pfnSCardTransmit = (void*)GetProcAddress(g_PCSCModule, "SCardTransmit"); - g_PCSC.pfnSCardListReaderGroups = (void*)GetProcAddress(g_PCSCModule, "SCardListReaderGroups"); - g_PCSC.pfnSCardListReaders = (void*)GetProcAddress(g_PCSCModule, "SCardListReaders"); - g_PCSC.pfnSCardCancel = (void*)GetProcAddress(g_PCSCModule, "SCardCancel"); - g_PCSC.pfnSCardGetAttrib = (void*)GetProcAddress(g_PCSCModule, "SCardGetAttrib"); - g_PCSC.pfnSCardSetAttrib = (void*)GetProcAddress(g_PCSCModule, "SCardSetAttrib"); + g_PCSC.pfnSCardTransmit = (fnPCSCSCardTransmit)GetProcAddress(g_PCSCModule, "SCardTransmit"); + g_PCSC.pfnSCardListReaderGroups = + (fnPCSCSCardListReaderGroups)GetProcAddress(g_PCSCModule, "SCardListReaderGroups"); + g_PCSC.pfnSCardListReaders = + (fnPCSCSCardListReaders)GetProcAddress(g_PCSCModule, "SCardListReaders"); + g_PCSC.pfnSCardCancel = (fnPCSCSCardCancel)GetProcAddress(g_PCSCModule, "SCardCancel"); + g_PCSC.pfnSCardGetAttrib = (fnPCSCSCardGetAttrib)GetProcAddress(g_PCSCModule, "SCardGetAttrib"); + g_PCSC.pfnSCardSetAttrib = (fnPCSCSCardSetAttrib)GetProcAddress(g_PCSCModule, "SCardSetAttrib"); g_PCSC.pfnSCardFreeMemory = NULL; #ifndef __APPLE__ - g_PCSC.pfnSCardFreeMemory = (void*)GetProcAddress(g_PCSCModule, "SCardFreeMemory"); + g_PCSC.pfnSCardFreeMemory = + (fnPCSCSCardFreeMemory)GetProcAddress(g_PCSCModule, "SCardFreeMemory"); #endif if (g_PCSC.pfnSCardFreeMemory) diff --git a/winpr/libwinpr/smartcard/smartcard_pcsc.h b/winpr/libwinpr/smartcard/smartcard_pcsc.h index 55df1cb23..9ff822d12 100644 --- a/winpr/libwinpr/smartcard/smartcard_pcsc.h +++ b/winpr/libwinpr/smartcard/smartcard_pcsc.h @@ -3,6 +3,8 @@ * Smart Card API * * Copyright 2014 Marc-Andre Moreau + * Copyright 2020 Armin Novak + * Copyright 2020 Thincast Technologies GmbH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,17 +42,68 @@ */ #ifdef __APPLE__ -typedef unsigned int PCSC_DWORD; -typedef PCSC_DWORD *PCSC_PDWORD, *PCSC_LPDWORD; -typedef unsigned int PCSC_ULONG; + +#include + +#ifndef BYTE +typedef uint8_t PCSC_BYTE; +#endif +typedef uint8_t PCSC_UCHAR; +typedef PCSC_UCHAR* PCSC_PUCHAR; +typedef uint16_t PCSC_USHORT; + +#ifndef __COREFOUNDATION_CFPLUGINCOM__ +typedef uint32_t PCSC_ULONG; +typedef void* PCSC_LPVOID; +typedef int16_t PCSC_BOOL; +#endif + typedef PCSC_ULONG* PCSC_PULONG; -typedef int PCSC_LONG; +typedef const void* PCSC_LPCVOID; +typedef uint32_t PCSC_DWORD; +typedef PCSC_DWORD* PCSC_PDWORD; +typedef uint16_t PCSC_WORD; +typedef int32_t PCSC_LONG; +typedef const char* PCSC_LPCSTR; +typedef const PCSC_BYTE* PCSC_LPCBYTE; +typedef PCSC_BYTE* PCSC_LPBYTE; +typedef PCSC_DWORD* PCSC_LPDWORD; +typedef char* PCSC_LPSTR; + #else -typedef unsigned long PCSC_DWORD; -typedef PCSC_DWORD *PCSC_PDWORD, *PCSC_LPDWORD; + +#ifndef BYTE +typedef unsigned char PCSC_BYTE; +#endif +typedef unsigned char PCSC_UCHAR; +typedef PCSC_UCHAR* PCSC_PUCHAR; +typedef unsigned short PCSC_USHORT; + +#ifndef __COREFOUNDATION_CFPLUGINCOM__ typedef unsigned long PCSC_ULONG; -typedef PCSC_ULONG* PCSC_PULONG; +typedef void* PCSC_LPVOID; +#endif + +typedef const void* PCSC_LPCVOID; +typedef unsigned long PCSC_DWORD; +typedef PCSC_DWORD* PCSC_PDWORD; typedef long PCSC_LONG; +typedef const char* PCSC_LPCSTR; +typedef const PCSC_BYTE* PCSC_LPCBYTE; +typedef PCSC_BYTE* PCSC_LPBYTE; +typedef PCSC_DWORD* PCSC_LPDWORD; +typedef char* PCSC_LPSTR; + +/* these types were deprecated but still used by old drivers and + * applications. So just declare and use them. */ +typedef PCSC_LPSTR PCSC_LPTSTR; +typedef PCSC_LPCSTR PCSC_LPCTSTR; + +/* types unused by pcsc-lite */ +typedef short PCSC_BOOL; +typedef unsigned short PCSC_WORD; +typedef PCSC_ULONG* PCSC_PULONG; + #endif #define PCSC_SCARD_UNKNOWN 0x0001 @@ -61,8 +114,8 @@ typedef long PCSC_LONG; #define PCSC_SCARD_NEGOTIABLE 0x0020 #define PCSC_SCARD_SPECIFIC 0x0040 -#define PCSC_SCARD_PROTOCOL_RAW 0x00000004 -#define PCSC_SCARD_PROTOCOL_T15 0x00000008 +#define PCSC_SCARD_PROTOCOL_RAW 0x00000004u +#define PCSC_SCARD_PROTOCOL_T15 0x00000008u #define PCSC_MAX_BUFFER_SIZE 264 #define PCSC_MAX_BUFFER_SIZE_EXTENDED (4 + 3 + (1 << 16) + 3 + 2) @@ -71,10 +124,6 @@ typedef long PCSC_LONG; #define PCSC_SCARD_AUTOALLOCATE (PCSC_DWORD)(-1) -#define PCSC_SCARD_PCI_T0 (&g_PCSC_rgSCardT0Pci) -#define PCSC_SCARD_PCI_T1 (&g_PCSC_rgSCardT1Pci) -#define PCSC_SCARD_PCI_RAW (&g_PCSC_rgSCardRawPci) - #define PCSC_SCARD_CTL_CODE(code) (0x42000000 + (code)) #define PCSC_CM_IOCTL_GET_FEATURE_REQUEST PCSC_SCARD_CTL_CODE(3400) @@ -118,49 +167,8 @@ typedef struct #pragma pack(pop) -struct _PCSCFunctionTable -{ - PCSC_LONG(*pfnSCardEstablishContext) - (PCSC_DWORD dwScope, LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext); - PCSC_LONG (*pfnSCardReleaseContext)(SCARDCONTEXT hContext); - PCSC_LONG (*pfnSCardIsValidContext)(SCARDCONTEXT hContext); - PCSC_LONG(*pfnSCardConnect) - (SCARDCONTEXT hContext, LPCSTR szReader, PCSC_DWORD dwShareMode, - PCSC_DWORD dwPreferredProtocols, LPSCARDHANDLE phCard, PCSC_LPDWORD pdwActiveProtocol); - PCSC_LONG(*pfnSCardReconnect) - (SCARDHANDLE hCard, PCSC_DWORD dwShareMode, PCSC_DWORD dwPreferredProtocols, - PCSC_DWORD dwInitialization, PCSC_LPDWORD pdwActiveProtocol); - PCSC_LONG (*pfnSCardDisconnect)(SCARDHANDLE hCard, PCSC_DWORD dwDisposition); - PCSC_LONG (*pfnSCardBeginTransaction)(SCARDHANDLE hCard); - PCSC_LONG (*pfnSCardEndTransaction)(SCARDHANDLE hCard, PCSC_DWORD dwDisposition); - PCSC_LONG(*pfnSCardStatus) - (SCARDHANDLE hCard, LPSTR mszReaderName, PCSC_LPDWORD pcchReaderLen, PCSC_LPDWORD pdwState, - PCSC_LPDWORD pdwProtocol, LPBYTE pbAtr, PCSC_LPDWORD pcbAtrLen); - PCSC_LONG(*pfnSCardGetStatusChange) - (SCARDCONTEXT hContext, PCSC_DWORD dwTimeout, PCSC_SCARD_READERSTATE* rgReaderStates, - PCSC_DWORD cReaders); - PCSC_LONG(*pfnSCardControl) - (SCARDHANDLE hCard, PCSC_DWORD dwControlCode, LPCVOID pbSendBuffer, PCSC_DWORD cbSendLength, - LPVOID pbRecvBuffer, PCSC_DWORD cbRecvLength, PCSC_LPDWORD lpBytesReturned); - PCSC_LONG(*pfnSCardTransmit) - (SCARDHANDLE hCard, const PCSC_SCARD_IO_REQUEST* pioSendPci, LPCBYTE pbSendBuffer, - PCSC_DWORD cbSendLength, PCSC_SCARD_IO_REQUEST* pioRecvPci, LPBYTE pbRecvBuffer, - PCSC_LPDWORD pcbRecvLength); - PCSC_LONG(*pfnSCardListReaderGroups) - (SCARDCONTEXT hContext, LPSTR mszGroups, PCSC_LPDWORD pcchGroups); - PCSC_LONG(*pfnSCardListReaders) - (SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders, PCSC_LPDWORD pcchReaders); - PCSC_LONG (*pfnSCardFreeMemory)(SCARDCONTEXT hContext, LPCVOID pvMem); - PCSC_LONG (*pfnSCardCancel)(SCARDCONTEXT hContext); - PCSC_LONG(*pfnSCardGetAttrib) - (SCARDHANDLE hCard, PCSC_DWORD dwAttrId, LPBYTE pbAttr, PCSC_LPDWORD pcbAttrLen); - PCSC_LONG(*pfnSCardSetAttrib) - (SCARDHANDLE hCard, PCSC_DWORD dwAttrId, LPCBYTE pbAttr, PCSC_DWORD cbAttrLen); -}; -typedef struct _PCSCFunctionTable PCSCFunctionTable; - int PCSC_InitializeSCardApi(void); -PSCardApiFunctionTable PCSC_GetSCardApiFunctionTable(void); +const SCardApiFunctionTable* PCSC_GetSCardApiFunctionTable(void); #endif