channels/smartcard: improve SCardGetAttrib
This commit is contained in:
parent
46686d391f
commit
b91c10392f
@ -932,39 +932,18 @@ static UINT32 smartcard_GetAttrib(SMARTCARD_DEVICE* smartcard, IRP* irp)
|
|||||||
hContext = (ULONG_PTR) call.hCard.Context.pbContext;
|
hContext = (ULONG_PTR) call.hCard.Context.pbContext;
|
||||||
|
|
||||||
ret.pbAttr = NULL;
|
ret.pbAttr = NULL;
|
||||||
cbAttrLen = (!call.cbAttrLen || call.fpbAttrIsNULL) ? 0 : SCARD_AUTOALLOCATE;
|
|
||||||
|
|
||||||
status = ret.ReturnCode = SCardGetAttrib(hCard, call.dwAttrId,
|
if (call.fpbAttrIsNULL)
|
||||||
(cbAttrLen == 0) ? NULL : (BYTE*) &ret.pbAttr, &cbAttrLen);
|
call.cbAttrLen = 0;
|
||||||
|
|
||||||
if (status)
|
if (call.cbAttrLen)
|
||||||
cbAttrLen = (call.cbAttrLen == 0) ? 0 : SCARD_AUTOALLOCATE;
|
ret.pbAttr = malloc(call.cbAttrLen);
|
||||||
|
|
||||||
if ((call.dwAttrId == SCARD_ATTR_DEVICE_FRIENDLY_NAME_A) && (status == SCARD_E_UNSUPPORTED_FEATURE))
|
cbAttrLen = call.cbAttrLen;
|
||||||
{
|
|
||||||
status = SCardGetAttrib(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME_W,
|
|
||||||
(cbAttrLen == 0) ? NULL : (BYTE*) &ret.pbAttr, &cbAttrLen);
|
|
||||||
|
|
||||||
if (status)
|
status = ret.ReturnCode = SCardGetAttrib(hCard, call.dwAttrId, ret.pbAttr, &cbAttrLen);
|
||||||
cbAttrLen = (call.cbAttrLen == 0) ? 0 : SCARD_AUTOALLOCATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((call.dwAttrId == SCARD_ATTR_DEVICE_FRIENDLY_NAME_W) && (status == SCARD_E_UNSUPPORTED_FEATURE))
|
ret.cbAttrLen = cbAttrLen;
|
||||||
{
|
|
||||||
status = SCardGetAttrib(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME_A,
|
|
||||||
(cbAttrLen == 0) ? NULL : (BYTE*) &ret.pbAttr, &cbAttrLen);
|
|
||||||
|
|
||||||
if (status)
|
|
||||||
cbAttrLen = (call.cbAttrLen == 0) ? 0 : SCARD_AUTOALLOCATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((cbAttrLen > call.cbAttrLen) && (ret.pbAttr))
|
|
||||||
status = SCARD_E_INSUFFICIENT_BUFFER;
|
|
||||||
|
|
||||||
ret.ReturnCode = status;
|
|
||||||
|
|
||||||
call.cbAttrLen = cbAttrLen;
|
|
||||||
ret.cbAttrLen = call.cbAttrLen;
|
|
||||||
|
|
||||||
if (ret.ReturnCode)
|
if (ret.ReturnCode)
|
||||||
{
|
{
|
||||||
@ -977,7 +956,7 @@ static UINT32 smartcard_GetAttrib(SMARTCARD_DEVICE* smartcard, IRP* irp)
|
|||||||
if (status)
|
if (status)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
SCardFreeMemory(hContext, ret.pbAttr);
|
free(ret.pbAttr);
|
||||||
|
|
||||||
return ret.ReturnCode;
|
return ret.ReturnCode;
|
||||||
}
|
}
|
||||||
|
@ -1104,6 +1104,7 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
WINSCARDAPI const char* WINAPI SCardGetErrorString(LONG errorCode);
|
WINSCARDAPI const char* WINAPI SCardGetErrorString(LONG errorCode);
|
||||||
|
WINSCARDAPI const char* WINAPI SCardGetAttributeString(DWORD dwAttrId);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -640,6 +640,147 @@ WINSCARDAPI const char* WINAPI SCardGetErrorString(LONG errorCode)
|
|||||||
return "SCARD_E_UNKNOWN";
|
return "SCARD_E_UNKNOWN";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WINSCARDAPI const char* WINAPI SCardGetAttributeString(DWORD dwAttrId)
|
||||||
|
{
|
||||||
|
switch (dwAttrId)
|
||||||
|
{
|
||||||
|
case SCARD_ATTR_VENDOR_NAME:
|
||||||
|
return "SCARD_ATTR_VENDOR_NAME";
|
||||||
|
break;
|
||||||
|
case SCARD_ATTR_VENDOR_IFD_TYPE:
|
||||||
|
return "SCARD_ATTR_VENDOR_IFD_TYPE";
|
||||||
|
break;
|
||||||
|
case SCARD_ATTR_VENDOR_IFD_VERSION:
|
||||||
|
return "SCARD_ATTR_VENDOR_IFD_VERSION";
|
||||||
|
break;
|
||||||
|
case SCARD_ATTR_VENDOR_IFD_SERIAL_NO:
|
||||||
|
return "SCARD_ATTR_VENDOR_IFD_SERIAL_NO";
|
||||||
|
break;
|
||||||
|
case SCARD_ATTR_CHANNEL_ID:
|
||||||
|
return "SCARD_ATTR_CHANNEL_ID";
|
||||||
|
break;
|
||||||
|
case SCARD_ATTR_PROTOCOL_TYPES:
|
||||||
|
return "SCARD_ATTR_PROTOCOL_TYPES";
|
||||||
|
break;
|
||||||
|
case SCARD_ATTR_DEFAULT_CLK:
|
||||||
|
return "SCARD_ATTR_DEFAULT_CLK";
|
||||||
|
break;
|
||||||
|
case SCARD_ATTR_MAX_CLK:
|
||||||
|
return "SCARD_ATTR_MAX_CLK";
|
||||||
|
break;
|
||||||
|
case SCARD_ATTR_DEFAULT_DATA_RATE:
|
||||||
|
return "SCARD_ATTR_DEFAULT_DATA_RATE";
|
||||||
|
break;
|
||||||
|
case SCARD_ATTR_MAX_DATA_RATE:
|
||||||
|
return "SCARD_ATTR_MAX_DATA_RATE";
|
||||||
|
break;
|
||||||
|
case SCARD_ATTR_MAX_IFSD:
|
||||||
|
return "SCARD_ATTR_MAX_IFSD";
|
||||||
|
break;
|
||||||
|
case SCARD_ATTR_POWER_MGMT_SUPPORT:
|
||||||
|
return "SCARD_ATTR_POWER_MGMT_SUPPORT";
|
||||||
|
break;
|
||||||
|
case SCARD_ATTR_USER_TO_CARD_AUTH_DEVICE:
|
||||||
|
return "SCARD_ATTR_USER_TO_CARD_AUTH_DEVICE";
|
||||||
|
break;
|
||||||
|
case SCARD_ATTR_USER_AUTH_INPUT_DEVICE:
|
||||||
|
return "SCARD_ATTR_USER_AUTH_INPUT_DEVICE";
|
||||||
|
break;
|
||||||
|
case SCARD_ATTR_CHARACTERISTICS:
|
||||||
|
return "SCARD_ATTR_CHARACTERISTICS";
|
||||||
|
break;
|
||||||
|
case SCARD_ATTR_CURRENT_PROTOCOL_TYPE:
|
||||||
|
return "SCARD_ATTR_CURRENT_PROTOCOL_TYPE";
|
||||||
|
break;
|
||||||
|
case SCARD_ATTR_CURRENT_CLK:
|
||||||
|
return "SCARD_ATTR_CURRENT_CLK";
|
||||||
|
break;
|
||||||
|
case SCARD_ATTR_CURRENT_F:
|
||||||
|
return "SCARD_ATTR_CURRENT_F";
|
||||||
|
break;
|
||||||
|
case SCARD_ATTR_CURRENT_D:
|
||||||
|
return "SCARD_ATTR_CURRENT_D";
|
||||||
|
break;
|
||||||
|
case SCARD_ATTR_CURRENT_N:
|
||||||
|
return "SCARD_ATTR_CURRENT_N";
|
||||||
|
break;
|
||||||
|
case SCARD_ATTR_CURRENT_W:
|
||||||
|
return "SCARD_ATTR_CURRENT_W";
|
||||||
|
break;
|
||||||
|
case SCARD_ATTR_CURRENT_IFSC:
|
||||||
|
return "SCARD_ATTR_CURRENT_IFSC";
|
||||||
|
break;
|
||||||
|
case SCARD_ATTR_CURRENT_IFSD:
|
||||||
|
return "SCARD_ATTR_CURRENT_IFSD";
|
||||||
|
break;
|
||||||
|
case SCARD_ATTR_CURRENT_BWT:
|
||||||
|
return "SCARD_ATTR_CURRENT_BWT";
|
||||||
|
break;
|
||||||
|
case SCARD_ATTR_CURRENT_CWT:
|
||||||
|
return "SCARD_ATTR_CURRENT_CWT";
|
||||||
|
break;
|
||||||
|
case SCARD_ATTR_CURRENT_EBC_ENCODING:
|
||||||
|
return "SCARD_ATTR_CURRENT_EBC_ENCODING";
|
||||||
|
break;
|
||||||
|
case SCARD_ATTR_EXTENDED_BWT:
|
||||||
|
return "SCARD_ATTR_EXTENDED_BWT";
|
||||||
|
break;
|
||||||
|
case SCARD_ATTR_ICC_PRESENCE:
|
||||||
|
return "SCARD_ATTR_ICC_PRESENCE";
|
||||||
|
break;
|
||||||
|
case SCARD_ATTR_ICC_INTERFACE_STATUS:
|
||||||
|
return "SCARD_ATTR_ICC_INTERFACE_STATUS";
|
||||||
|
break;
|
||||||
|
case SCARD_ATTR_CURRENT_IO_STATE:
|
||||||
|
return "SCARD_ATTR_CURRENT_IO_STATE";
|
||||||
|
break;
|
||||||
|
case SCARD_ATTR_ATR_STRING:
|
||||||
|
return "SCARD_ATTR_ATR_STRING";
|
||||||
|
break;
|
||||||
|
case SCARD_ATTR_ICC_TYPE_PER_ATR:
|
||||||
|
return "SCARD_ATTR_ICC_TYPE_PER_ATR";
|
||||||
|
break;
|
||||||
|
case SCARD_ATTR_ESC_RESET:
|
||||||
|
return "SCARD_ATTR_ESC_RESET";
|
||||||
|
break;
|
||||||
|
case SCARD_ATTR_ESC_CANCEL:
|
||||||
|
return "SCARD_ATTR_ESC_CANCEL";
|
||||||
|
break;
|
||||||
|
case SCARD_ATTR_ESC_AUTHREQUEST:
|
||||||
|
return "SCARD_ATTR_ESC_AUTHREQUEST";
|
||||||
|
break;
|
||||||
|
case SCARD_ATTR_MAXINPUT:
|
||||||
|
return "SCARD_ATTR_MAXINPUT";
|
||||||
|
break;
|
||||||
|
case SCARD_ATTR_DEVICE_UNIT:
|
||||||
|
return "SCARD_ATTR_DEVICE_UNIT";
|
||||||
|
break;
|
||||||
|
case SCARD_ATTR_DEVICE_IN_USE:
|
||||||
|
return "SCARD_ATTR_DEVICE_IN_USE";
|
||||||
|
break;
|
||||||
|
case SCARD_ATTR_DEVICE_FRIENDLY_NAME_A:
|
||||||
|
return "SCARD_ATTR_DEVICE_FRIENDLY_NAME_A";
|
||||||
|
break;
|
||||||
|
case SCARD_ATTR_DEVICE_SYSTEM_NAME_A:
|
||||||
|
return "SCARD_ATTR_DEVICE_SYSTEM_NAME_A";
|
||||||
|
break;
|
||||||
|
case SCARD_ATTR_DEVICE_FRIENDLY_NAME_W:
|
||||||
|
return "SCARD_ATTR_DEVICE_FRIENDLY_NAME_W";
|
||||||
|
break;
|
||||||
|
case SCARD_ATTR_DEVICE_SYSTEM_NAME_W:
|
||||||
|
return "SCARD_ATTR_DEVICE_SYSTEM_NAME_W";
|
||||||
|
break;
|
||||||
|
case SCARD_ATTR_SUPRESS_T1_IFS_REQUEST:
|
||||||
|
return "SCARD_ATTR_SUPRESS_T1_IFS_REQUEST";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return "SCARD_ATTR_UNKNOWN";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return "SCARD_ATTR_UNKNOWN";
|
||||||
|
}
|
||||||
|
|
||||||
void InitializeSCardApiStubs(void)
|
void InitializeSCardApiStubs(void)
|
||||||
{
|
{
|
||||||
g_Initialized = TRUE;
|
g_Initialized = TRUE;
|
||||||
|
@ -38,6 +38,8 @@ static BOOL g_SCardAutoAllocate = FALSE;
|
|||||||
static wListDictionary* g_SmartCards = NULL;
|
static wListDictionary* g_SmartCards = NULL;
|
||||||
static wListDictionary* g_MemoryBlocks = NULL;
|
static wListDictionary* g_MemoryBlocks = NULL;
|
||||||
|
|
||||||
|
WINSCARDAPI LONG WINAPI PCSC_SCardFreeMemory(SCARDCONTEXT hContext, LPCVOID pvMem);
|
||||||
|
|
||||||
LONG PCSC_MapErrorCodeToWinSCard(LONG errorCode)
|
LONG PCSC_MapErrorCodeToWinSCard(LONG errorCode)
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@ -315,10 +317,7 @@ WINSCARDAPI LONG WINAPI PCSC_SCardListReadersW(SCARDCONTEXT hContext,
|
|||||||
ConvertToUnicode(CP_UTF8, 0, mszReadersA, length + 2, (WCHAR**) mszReaders, 0);
|
ConvertToUnicode(CP_UTF8, 0, mszReadersA, length + 2, (WCHAR**) mszReaders, 0);
|
||||||
PCSC_AddMemoryBlock(hContext, mszReaders);
|
PCSC_AddMemoryBlock(hContext, mszReaders);
|
||||||
|
|
||||||
if (g_PCSC.pfnSCardFreeMemory)
|
PCSC_SCardFreeMemory(hContext, mszReadersA);
|
||||||
{
|
|
||||||
g_PCSC.pfnSCardFreeMemory(hContext, mszReadersA);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -484,14 +483,14 @@ WINSCARDAPI LONG WINAPI PCSC_SCardFreeMemory(SCARDCONTEXT hContext, LPCVOID pvMe
|
|||||||
{
|
{
|
||||||
LONG status = SCARD_S_SUCCESS;
|
LONG status = SCARD_S_SUCCESS;
|
||||||
|
|
||||||
if (g_PCSC.pfnSCardFreeMemory)
|
|
||||||
{
|
|
||||||
if (PCSC_RemoveMemoryBlock(hContext, (void*) pvMem))
|
if (PCSC_RemoveMemoryBlock(hContext, (void*) pvMem))
|
||||||
{
|
{
|
||||||
free((void*) pvMem);
|
free((void*) pvMem);
|
||||||
status = SCARD_S_SUCCESS;
|
status = SCARD_S_SUCCESS;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (g_PCSC.pfnSCardFreeMemory)
|
||||||
{
|
{
|
||||||
status = g_PCSC.pfnSCardFreeMemory(hContext, pvMem);
|
status = g_PCSC.pfnSCardFreeMemory(hContext, pvMem);
|
||||||
status = PCSC_MapErrorCodeToWinSCard(status);
|
status = PCSC_MapErrorCodeToWinSCard(status);
|
||||||
@ -734,13 +733,9 @@ WINSCARDAPI LONG WINAPI PCSC_SCardState(SCARDHANDLE hCard,
|
|||||||
status = PCSC_MapErrorCodeToWinSCard(status);
|
status = PCSC_MapErrorCodeToWinSCard(status);
|
||||||
|
|
||||||
if (mszReaderNames)
|
if (mszReaderNames)
|
||||||
{
|
|
||||||
if (g_PCSC.pfnSCardFreeMemory)
|
|
||||||
{
|
{
|
||||||
hContext = PCSC_GetSmartCardContextFromHandle(hCard);
|
hContext = PCSC_GetSmartCardContextFromHandle(hCard);
|
||||||
|
PCSC_SCardFreeMemory(hContext, mszReaderNames);
|
||||||
g_PCSC.pfnSCardFreeMemory(hContext, mszReaderNames);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -926,10 +921,7 @@ WINSCARDAPI LONG WINAPI PCSC_SCardStatusW(SCARDHANDLE hCard,
|
|||||||
|
|
||||||
PCSC_AddMemoryBlock(hContext, mszReaderNames);
|
PCSC_AddMemoryBlock(hContext, mszReaderNames);
|
||||||
|
|
||||||
if (g_PCSC.pfnSCardFreeMemory)
|
PCSC_SCardFreeMemory(hContext, mszReaderNamesA);
|
||||||
{
|
|
||||||
g_PCSC.pfnSCardFreeMemory(hContext, mszReaderNamesA);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -974,7 +966,7 @@ WINSCARDAPI LONG WINAPI PCSC_SCardControl(SCARDHANDLE hCard,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
WINSCARDAPI LONG WINAPI PCSC_SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr, LPDWORD pcbAttrLen)
|
WINSCARDAPI LONG WINAPI PCSC_SCardGetAttrib_Internal(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr, LPDWORD pcbAttrLen)
|
||||||
{
|
{
|
||||||
LONG status = SCARD_S_SUCCESS;
|
LONG status = SCARD_S_SUCCESS;
|
||||||
|
|
||||||
@ -1024,6 +1016,110 @@ WINSCARDAPI LONG WINAPI PCSC_SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, L
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WINSCARDAPI LONG WINAPI PCSC_SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr, LPDWORD pcbAttrLen)
|
||||||
|
{
|
||||||
|
LONG status = SCARD_S_SUCCESS;
|
||||||
|
|
||||||
|
status = PCSC_SCardGetAttrib_Internal(hCard, dwAttrId, pbAttr, pcbAttrLen);
|
||||||
|
|
||||||
|
if (status == SCARD_E_UNSUPPORTED_FEATURE)
|
||||||
|
{
|
||||||
|
DWORD cbAttrLen;
|
||||||
|
SCARDCONTEXT hContext;
|
||||||
|
BOOL attrAutoAlloc = FALSE;
|
||||||
|
LPBYTE* pPbAttr = (LPBYTE*) pbAttr;
|
||||||
|
|
||||||
|
cbAttrLen = *pcbAttrLen;
|
||||||
|
|
||||||
|
if (*pcbAttrLen == SCARD_AUTOALLOCATE)
|
||||||
|
attrAutoAlloc = TRUE;
|
||||||
|
|
||||||
|
hContext = PCSC_GetSmartCardContextFromHandle(hCard);
|
||||||
|
|
||||||
|
if (dwAttrId == SCARD_ATTR_DEVICE_FRIENDLY_NAME_A)
|
||||||
|
{
|
||||||
|
WCHAR* pbAttrW = NULL;
|
||||||
|
|
||||||
|
*pcbAttrLen = SCARD_AUTOALLOCATE;
|
||||||
|
|
||||||
|
status = PCSC_SCardGetAttrib_Internal(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME_W,
|
||||||
|
(LPBYTE) &pbAttrW, pcbAttrLen);
|
||||||
|
|
||||||
|
if (status)
|
||||||
|
{
|
||||||
|
int length;
|
||||||
|
char* pbAttrA = NULL;
|
||||||
|
|
||||||
|
length = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) pbAttrW,
|
||||||
|
*pcbAttrLen, (char**) &pbAttrA, 0, NULL, NULL);
|
||||||
|
|
||||||
|
PCSC_SCardFreeMemory(hContext, pbAttrW);
|
||||||
|
|
||||||
|
if (attrAutoAlloc)
|
||||||
|
{
|
||||||
|
PCSC_AddMemoryBlock(hContext, pbAttrA);
|
||||||
|
*pPbAttr = (BYTE*) pbAttrA;
|
||||||
|
*pcbAttrLen = length;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (length > cbAttrLen)
|
||||||
|
{
|
||||||
|
free(pbAttrA);
|
||||||
|
return SCARD_E_INSUFFICIENT_BUFFER;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CopyMemory(pbAttr, (BYTE*) pbAttrA, length);
|
||||||
|
*pcbAttrLen = length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (dwAttrId == SCARD_ATTR_DEVICE_FRIENDLY_NAME_W)
|
||||||
|
{
|
||||||
|
char* pbAttrA = NULL;
|
||||||
|
|
||||||
|
*pcbAttrLen = SCARD_AUTOALLOCATE;
|
||||||
|
|
||||||
|
status = PCSC_SCardGetAttrib_Internal(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME_A,
|
||||||
|
(LPBYTE) &pbAttrA, pcbAttrLen);
|
||||||
|
|
||||||
|
if (status)
|
||||||
|
{
|
||||||
|
int length;
|
||||||
|
WCHAR* pbAttrW = NULL;
|
||||||
|
|
||||||
|
length = ConvertToUnicode(CP_UTF8, 0, (char*) pbAttr, *pcbAttrLen, &pbAttrW, 0) * 2;
|
||||||
|
|
||||||
|
PCSC_SCardFreeMemory(hContext, pbAttrA);
|
||||||
|
|
||||||
|
if (attrAutoAlloc)
|
||||||
|
{
|
||||||
|
PCSC_AddMemoryBlock(hContext, pbAttrW);
|
||||||
|
*pPbAttr = (BYTE*) pbAttrW;
|
||||||
|
*pcbAttrLen = length;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (length > cbAttrLen)
|
||||||
|
{
|
||||||
|
free(pbAttrW);
|
||||||
|
return SCARD_E_INSUFFICIENT_BUFFER;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CopyMemory(pbAttr, (BYTE*) pbAttrW, length);
|
||||||
|
*pcbAttrLen = length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
WINSCARDAPI LONG WINAPI PCSC_SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPCBYTE pbAttr, DWORD cbAttrLen)
|
WINSCARDAPI LONG WINAPI PCSC_SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPCBYTE pbAttr, DWORD cbAttrLen)
|
||||||
{
|
{
|
||||||
LONG status = SCARD_S_SUCCESS;
|
LONG status = SCARD_S_SUCCESS;
|
||||||
|
Loading…
Reference in New Issue
Block a user