{
SCARDCONTEXT hContext = 0;
- if (context->cbContext != sizeof(ULONG_PTR))
+ if ((context->cbContext != sizeof(ULONG_PTR)) && (context->cbContext != 0))
{
WLog_Print(smartcard->log, WLOG_WARN,
"REDIR_SCARDCONTEXT does not match native size: Actual: %d, Expected: %d",
if (context->cbContext)
CopyMemory(&hContext, &(context->pbContext), context->cbContext);
+ else
+ ZeroMemory(&hContext, sizeof(ULONG_PTR));
return hContext;
}
Stream_Read_UINT32(s, context->cbContext); /* cbContext (4 bytes) */
- if ((Stream_GetRemainingLength(s) < context->cbContext) || (!context->cbContext))
+ if (Stream_GetRemainingLength(s) < context->cbContext)
{
WLog_Print(smartcard->log, WLOG_WARN, "REDIR_SCARDCONTEXT is too short: Actual: %d, Expected: %d",
(int) Stream_GetRemainingLength(s), context->cbContext);
return STATUS_BUFFER_TOO_SMALL;
}
- if ((context->cbContext != 4) && (context->cbContext != 8))
+ if ((context->cbContext != 0) && (context->cbContext != 4) && (context->cbContext != 8))
{
- WLog_Print(smartcard->log, WLOG_WARN, "REDIR_SCARDCONTEXT length is not 4 or 8: %d\n", context->cbContext);
+ WLog_Print(smartcard->log, WLOG_WARN, "REDIR_SCARDCONTEXT length is not 0, 4 or 8: %d\n", context->cbContext);
return STATUS_INVALID_PARAMETER;
}
Stream_Read_UINT32(s, pbContextNdrPtr); /* pbContextNdrPtr (4 bytes) */
+ if (((context->cbContext == 0) && pbContextNdrPtr) || ((context->cbContext != 0) && !pbContextNdrPtr))
+ {
+ WLog_Print(smartcard->log, WLOG_WARN, "REDIR_SCARDCONTEXT cbContext (%d) pbContextNdrPtr (%d) inconsistency",
+ (int) context->cbContext, (int) pbContextNdrPtr);
+ return STATUS_INVALID_PARAMETER;
+ }
+
if (context->cbContext > Stream_GetRemainingLength(s))
{
WLog_Print(smartcard->log, WLOG_WARN, "REDIR_SCARDCONTEXT is too long: Actual: %d, Expected: %d",
{
UINT32 length;
+ if (context->cbContext == 0)
+ return SCARD_S_SUCCESS;
+
if (Stream_GetRemainingLength(s) < 4)
{
WLog_Print(smartcard->log, WLOG_WARN, "REDIR_SCARDCONTEXT is too short: Actual: %d, Expected: %d\n",
return STATUS_INVALID_PARAMETER;
}
- if ((context->cbContext != 4) && (context->cbContext != 8))
+ if ((context->cbContext != 0) && (context->cbContext != 4) && (context->cbContext != 8))
{
WLog_Print(smartcard->log, WLOG_WARN, "REDIR_SCARDCONTEXT length is not 4 or 8: %d\n", context->cbContext);
return STATUS_INVALID_PARAMETER;
}
- if ((Stream_GetRemainingLength(s) < context->cbContext) || (!context->cbContext))
+ if (Stream_GetRemainingLength(s) < context->cbContext)
{
WLog_Print(smartcard->log, WLOG_WARN, "REDIR_SCARDCONTEXT is too short: Actual: %d, Expected: %d\n",
(int) Stream_GetRemainingLength(s), context->cbContext);
if (context->cbContext)
Stream_Read(s, &(context->pbContext), context->cbContext);
+ else
+ ZeroMemory(&(context->pbContext), sizeof(context->pbContext));
return SCARD_S_SUCCESS;
}
return nameWinSCard;
}
+char* PCSC_GetReaderAliasFromName(char* namePCSC)
+{
+ char* nameWinSCard;
+
+ nameWinSCard = PCSC_ConvertReaderNameToWinSCard(namePCSC);
+
+ if (nameWinSCard)
+ PCSC_AddReaderNameAlias(namePCSC, nameWinSCard);
+
+ return nameWinSCard;
+}
+
char* PCSC_ConvertReaderNamesToWinSCard(const char* names, LPDWORD pcchReaders)
{
int length;
while ((p - names) < cchReaders)
{
- nameWinSCard = PCSC_ConvertReaderNameToWinSCard(p);
+ nameWinSCard = PCSC_GetReaderAliasFromName(p);
if (nameWinSCard)
{
- PCSC_AddReaderNameAlias(p, nameWinSCard);
-
length = strlen(nameWinSCard);
CopyMemory(q, nameWinSCard, length);
free(nameWinSCard);
status = (LONG) g_PCSC.pfnSCardEstablishContext(pcsc_dwScope, pvReserved1, pvReserved2, phContext);
status = PCSC_MapErrorCodeToWinSCard(status);
- if (!status)
+ if (status == SCARD_S_SUCCESS)
PCSC_EstablishCardContext(*phContext);
return status;
WINSCARDAPI LONG WINAPI PCSC_SCardListReadersA(SCARDCONTEXT hContext,
LPCSTR mszGroups, LPSTR mszReaders, LPDWORD pcchReaders)
{
+ BOOL nullCardContext = FALSE;
LONG status = SCARD_S_SUCCESS;
+ LPSTR* pMszReaders = (LPSTR*) mszReaders;
if (!g_PCSC.pfnSCardListReaders)
return SCARD_E_NO_SERVICE;
+ if (!hContext)
+ {
+ status = PCSC_SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
+
+ if (status != SCARD_S_SUCCESS)
+ return status;
+
+ nullCardContext = TRUE;
+ }
+
if (!PCSC_LockCardContext(hContext))
return SCARD_E_INVALID_HANDLE;
if (!PCSC_UnlockCardContext(hContext))
return SCARD_E_INVALID_HANDLE;
+ if (nullCardContext)
+ {
+ status = PCSC_SCardReleaseContext(hContext);
+ }
+
return status;
}
LPSTR mszReadersA = NULL;
LPSTR* pMszReadersA = &mszReadersA;
LONG status = SCARD_S_SUCCESS;
+ BOOL nullCardContext = FALSE;
if (!g_PCSC.pfnSCardListReaders)
return SCARD_E_NO_SERVICE;
+ if (!hContext)
+ {
+ status = PCSC_SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
+
+ if (status != SCARD_S_SUCCESS)
+ return status;
+
+ nullCardContext = TRUE;
+ }
+
if (!PCSC_LockCardContext(hContext))
return SCARD_E_INVALID_HANDLE;
if (!PCSC_UnlockCardContext(hContext))
return SCARD_E_INVALID_HANDLE;
+ if (nullCardContext)
+ {
+ status = PCSC_SCardReleaseContext(hContext);
+ }
+
return status;
}
{
LONG status = SCARD_S_SUCCESS;
- if (!PCSC_LockCardContext(hContext))
- return SCARD_E_INVALID_HANDLE;
+ if (hContext)
+ {
+ if (!PCSC_LockCardContext(hContext))
+ return SCARD_E_INVALID_HANDLE;
+ }
status = PCSC_SCardFreeMemory_Internal(hContext, pvMem);
- if (!PCSC_UnlockCardContext(hContext))
- return SCARD_E_INVALID_HANDLE;
+ if (hContext)
+ {
+ if (!PCSC_UnlockCardContext(hContext))
+ return SCARD_E_INVALID_HANDLE;
+ }
return status;
}
return status;
}
+WINSCARDAPI LONG WINAPI PCSC_SCardGetAttrib_FriendlyName(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr, LPDWORD pcbAttrLen)
+{
+ int length = 0;
+ char* namePCSC;
+ char* nameWinSCard;
+ char* pbAttrA = NULL;
+ WCHAR* pbAttrW = NULL;
+ SCARDCONTEXT hContext;
+ char* friendlyNameA = NULL;
+ WCHAR* friendlyNameW = NULL;
+ LONG status = SCARD_S_SUCCESS;
+ LPBYTE* pPbAttr = (LPBYTE*) pbAttr;
+
+ hContext = PCSC_GetCardContextFromHandle(hCard);
+
+ if (!hContext)
+ return SCARD_E_INVALID_HANDLE;
+
+ *pcbAttrLen = SCARD_AUTOALLOCATE;
+
+ status = PCSC_SCardGetAttrib_Internal(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME_A,
+ (LPBYTE) &pbAttrA, pcbAttrLen);
+
+ if (status != SCARD_S_SUCCESS)
+ {
+ pbAttrA = NULL;
+ *pcbAttrLen = SCARD_AUTOALLOCATE;
+
+ status = PCSC_SCardGetAttrib_Internal(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME_W,
+ (LPBYTE) &pbAttrW, pcbAttrLen);
+
+ if (status != SCARD_S_SUCCESS)
+ return status;
+
+ length = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) pbAttrW,
+ *pcbAttrLen, (char**) &pbAttrA, 0, NULL, NULL);
+
+ namePCSC = pbAttrA;
+ PCSC_SCardFreeMemory_Internal(hContext, pbAttrW);
+ }
+ else
+ {
+ namePCSC = _strdup(pbAttrA);
+
+ if (!namePCSC)
+ return SCARD_E_NO_MEMORY;
+
+ PCSC_SCardFreeMemory_Internal(hContext, pbAttrA);
+ }
+
+ length = strlen(namePCSC);
+ nameWinSCard = PCSC_GetReaderAliasFromName(namePCSC);
+
+ if (nameWinSCard)
+ {
+ length = strlen(nameWinSCard);
+ friendlyNameA = _strdup(nameWinSCard);
+
+ if (!friendlyNameA)
+ return SCARD_E_NO_MEMORY;
+ }
+ else
+ {
+ friendlyNameA = namePCSC;
+ }
+
+ if (dwAttrId == SCARD_ATTR_DEVICE_FRIENDLY_NAME_W)
+ {
+ length = ConvertToUnicode(CP_UTF8, 0, (char*) friendlyNameA, -1, &friendlyNameW, 0);
+
+ free(friendlyNameA);
+
+ if (!friendlyNameW)
+ return SCARD_E_NO_MEMORY;
+
+ if (*pcbAttrLen == SCARD_AUTOALLOCATE)
+ {
+ *pPbAttr = (BYTE*) friendlyNameW;
+ *pcbAttrLen = length * 2;
+ PCSC_AddMemoryBlock(hContext, *pPbAttr);
+ }
+ else
+ {
+ if (((length + 1) * 2) > *pcbAttrLen)
+ {
+ free(friendlyNameW);
+ return SCARD_E_INSUFFICIENT_BUFFER;
+ }
+ else
+ {
+ CopyMemory(pbAttr, (BYTE*) friendlyNameW, ((length + 1) * 2));
+ *pcbAttrLen = length * 2;
+ free(friendlyNameW);
+ }
+ }
+ }
+ else
+ {
+ if (*pcbAttrLen == SCARD_AUTOALLOCATE)
+ {
+ *pPbAttr = (BYTE*) friendlyNameA;
+ *pcbAttrLen = length;
+ PCSC_AddMemoryBlock(hContext, *pPbAttr);
+ }
+ else
+ {
+ if ((length + 1) > *pcbAttrLen)
+ {
+ free(friendlyNameA);
+ return SCARD_E_INSUFFICIENT_BUFFER;
+ }
+ else
+ {
+ CopyMemory(pbAttr, (BYTE*) friendlyNameA, length + 1);
+ *pcbAttrLen = length;
+ free(friendlyNameA);
+ }
+ }
+ }
+
+ return status;
+}
+
WINSCARDAPI LONG WINAPI PCSC_SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr, LPDWORD pcbAttrLen)
{
DWORD cbAttrLen;
hContext = PCSC_GetCardContextFromHandle(hCard);
+ if (!hContext)
+ return SCARD_E_INVALID_HANDLE;
+
+ if ((dwAttrId == SCARD_ATTR_DEVICE_FRIENDLY_NAME_A) || (dwAttrId == SCARD_ATTR_DEVICE_FRIENDLY_NAME_W))
+ {
+ return PCSC_SCardGetAttrib_FriendlyName(hCard, dwAttrId, pbAttr, pcbAttrLen);
+ }
+
status = PCSC_SCardGetAttrib_Internal(hCard, dwAttrId, pbAttr, pcbAttrLen);
if (status == SCARD_S_SUCCESS)
}
else
{
- 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 == SCARD_S_SUCCESS)
- {
- int length;
- char* pbAttrA = NULL;
-
- length = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) pbAttrW,
- *pcbAttrLen, (char**) &pbAttrA, 0, NULL, NULL);
-
- PCSC_SCardFreeMemory_Internal(hContext, pbAttrW);
-
- if (pcbAttrLenAlloc)
- {
- 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 == SCARD_S_SUCCESS)
- {
- int length;
- WCHAR* pbAttrW = NULL;
-
- length = ConvertToUnicode(CP_UTF8, 0, (char*) pbAttr, *pcbAttrLen, &pbAttrW, 0);
-
- PCSC_SCardFreeMemory_Internal(hContext, pbAttrA);
-
- if (pcbAttrLenAlloc)
- {
- 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;
- }
- }
- }
- }
- else if (dwAttrId == SCARD_ATTR_CURRENT_PROTOCOL_TYPE)
+ if (dwAttrId == SCARD_ATTR_CURRENT_PROTOCOL_TYPE)
{
PCSC_DWORD dwState = 0;
PCSC_DWORD cbAtrLen = 0;
if (cbAttrLen < 4)
return SCARD_E_INSUFFICIENT_BUFFER;
- *pdwProtocol = dwProtocol;
+ *pdwProtocol = PCSC_ConvertProtocolsToWinSCard(dwProtocol);
}
}
else if (dwAttrId == SCARD_ATTR_VENDOR_IFD_TYPE)