channels/smartcard: fix reader name aliasing
This commit is contained in:
parent
09a540b40b
commit
38d05b48a0
@ -145,32 +145,6 @@ const char* smartcard_get_ioctl_string(UINT32 ioControlCode, BOOL funcName)
|
|||||||
return funcName ? "SCardUnknown" : "SCARD_IOCTL_UNKNOWN";
|
return funcName ? "SCardUnknown" : "SCARD_IOCTL_UNKNOWN";
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t smartcard_multi_string_length_a(const char* msz)
|
|
||||||
{
|
|
||||||
char* p = (char*) msz;
|
|
||||||
|
|
||||||
if (!p)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
while ((p[0] != 0) && (p[1] != 0))
|
|
||||||
p++;
|
|
||||||
|
|
||||||
return (p - msz) + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t smartcard_multi_string_length_w(const WCHAR* msz)
|
|
||||||
{
|
|
||||||
WCHAR* p = (WCHAR*) msz;
|
|
||||||
|
|
||||||
if (!p)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
while ((p[0] != 0) && (p[1] != 0))
|
|
||||||
p++;
|
|
||||||
|
|
||||||
return (p - msz) + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static UINT32 smartcard_EstablishContext(SMARTCARD_DEVICE* smartcard, IRP* irp)
|
static UINT32 smartcard_EstablishContext(SMARTCARD_DEVICE* smartcard, IRP* irp)
|
||||||
{
|
{
|
||||||
UINT32 status;
|
UINT32 status;
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
#include <winpr/crt.h>
|
#include <winpr/crt.h>
|
||||||
|
#include <winpr/print.h>
|
||||||
#include <winpr/synch.h>
|
#include <winpr/synch.h>
|
||||||
#include <winpr/library.h>
|
#include <winpr/library.h>
|
||||||
#include <winpr/smartcard.h>
|
#include <winpr/smartcard.h>
|
||||||
@ -311,23 +312,38 @@ BOOL PCSC_AddReaderNameAlias(char* namePCSC, char* nameWinSCard)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int PCSC_AtoiWithLength(const char* str, int length)
|
||||||
|
{
|
||||||
|
int index;
|
||||||
|
int value = 0;
|
||||||
|
|
||||||
|
for (index = 0; index < length; ++index)
|
||||||
|
{
|
||||||
|
if (!isdigit(str[index]))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
value = value * 10 + (str[index] - '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
char* PCSC_ConvertReaderNameToWinSCard(const char* name)
|
char* PCSC_ConvertReaderNameToWinSCard(const char* name)
|
||||||
{
|
{
|
||||||
int slot;
|
int slot;
|
||||||
int index;
|
int index;
|
||||||
int size;
|
int size;
|
||||||
int length;
|
int length;
|
||||||
|
int ctoken;
|
||||||
|
int ntokens;
|
||||||
|
char *p, *q;
|
||||||
|
char* tokens[64][2];
|
||||||
char* nameWinSCard;
|
char* nameWinSCard;
|
||||||
char *na1, *na2 = NULL;
|
|
||||||
char *if1, *if2 = NULL;
|
|
||||||
char *se1, *se2 = NULL;
|
|
||||||
char *in1, *in2 = NULL;
|
|
||||||
char *sl1, *sl2 = NULL;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pcsc-lite reader name format:
|
* pcsc-lite reader name format:
|
||||||
*
|
|
||||||
* name [interface] (serial) index slot
|
* name [interface] (serial) index slot
|
||||||
|
*
|
||||||
* Athena IDProtect Key v2 [Main Interface] 00 00
|
* Athena IDProtect Key v2 [Main Interface] 00 00
|
||||||
*
|
*
|
||||||
* name: Athena IDProtect Key v2
|
* name: Athena IDProtect Key v2
|
||||||
@ -336,6 +352,22 @@ char* PCSC_ConvertReaderNameToWinSCard(const char* name)
|
|||||||
* index: 00
|
* index: 00
|
||||||
* slot: 00
|
* slot: 00
|
||||||
*
|
*
|
||||||
|
* Athena ASE IIIe 0
|
||||||
|
*
|
||||||
|
* name: Athena ASE IIIe
|
||||||
|
* interface: N/A
|
||||||
|
* serial: N/A
|
||||||
|
* index: 0
|
||||||
|
* slot: 0
|
||||||
|
*
|
||||||
|
* Athena ASE IIIe [CCID Bulk Interface] 00 00
|
||||||
|
*
|
||||||
|
* name: Athena ASE IIIe
|
||||||
|
* interface: CCID Bulk Interface
|
||||||
|
* serial: N/A
|
||||||
|
* index: 00
|
||||||
|
* slot: 00
|
||||||
|
*
|
||||||
* the serial component is optional
|
* the serial component is optional
|
||||||
* the index is a two digit zero-padded integer
|
* the index is a two digit zero-padded integer
|
||||||
* the slot is a two digit zero-padded integer
|
* the slot is a two digit zero-padded integer
|
||||||
@ -346,44 +378,75 @@ char* PCSC_ConvertReaderNameToWinSCard(const char* name)
|
|||||||
if (length < 10)
|
if (length < 10)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
na1 = (char*) name;
|
ntokens = 0;
|
||||||
na2 = (char*) &name[length - 7];
|
p = q = (char*) name;
|
||||||
|
|
||||||
if1 = strchr(name, '[');
|
while (*p)
|
||||||
|
{
|
||||||
|
if (*p == ' ')
|
||||||
|
{
|
||||||
|
tokens[ntokens][0] = q;
|
||||||
|
tokens[ntokens][1] = p;
|
||||||
|
q = p + 1;
|
||||||
|
ntokens++;
|
||||||
|
}
|
||||||
|
|
||||||
if (if1)
|
p++;
|
||||||
if2 = strchr(if1 + 1, ']');
|
}
|
||||||
|
|
||||||
se1 = strchr(name, '(');
|
tokens[ntokens][0] = q;
|
||||||
|
tokens[ntokens][1] = p;
|
||||||
|
ntokens++;
|
||||||
|
|
||||||
if (se1)
|
if (ntokens < 2)
|
||||||
se2 = strchr(se1 + 1, ')');
|
|
||||||
|
|
||||||
in1 = (char*) &name[length - 5];
|
|
||||||
in2 = (char*) &name[length - 4];
|
|
||||||
|
|
||||||
sl1 = (char*) &name[length - 2];
|
|
||||||
sl2 = (char*) &name[length - 1];
|
|
||||||
|
|
||||||
if (!(if1 && if2))
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!(isdigit(*in1) && isdigit(*in2)))
|
slot = index = -1;
|
||||||
|
ctoken = ntokens - 1;
|
||||||
|
|
||||||
|
slot = PCSC_AtoiWithLength(tokens[ctoken][0], (int) (tokens[ctoken][1] - tokens[ctoken][0]));
|
||||||
|
ctoken--;
|
||||||
|
|
||||||
|
index = PCSC_AtoiWithLength(tokens[ctoken][0], (int) (tokens[ctoken][1] - tokens[ctoken][0]));
|
||||||
|
ctoken--;
|
||||||
|
|
||||||
|
if (index < 0)
|
||||||
|
{
|
||||||
|
slot = -1;
|
||||||
|
index = slot;
|
||||||
|
ctoken++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((index < 0) || (slot < 0))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!(isdigit(*sl1) && isdigit(*sl2)))
|
if (*(tokens[ctoken][1] - 1) == ')')
|
||||||
|
{
|
||||||
|
while ((*(tokens[ctoken][0]) != '(') && (ctoken > 0))
|
||||||
|
ctoken--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctoken < 1)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
na2 = if1 - 1;
|
if (*(tokens[ctoken][1] - 1) == ']')
|
||||||
|
{
|
||||||
|
while ((*(tokens[ctoken][0]) != '[') && (ctoken > 0))
|
||||||
|
ctoken--;
|
||||||
|
}
|
||||||
|
|
||||||
while ((*na2 == ' ') && (na2 > na1))
|
if (ctoken < 1)
|
||||||
na2--;
|
return NULL;
|
||||||
na2++;
|
|
||||||
|
|
||||||
index = ((*in1 - 0x30) * 10) + (*in2 - 0x30);
|
ctoken--;
|
||||||
slot = ((*sl1 - 0x30) * 10) + (*sl2 - 0x30);
|
|
||||||
|
|
||||||
length = (na2 - na1);
|
if (ctoken < 1)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
p = tokens[0][0];
|
||||||
|
q = tokens[ctoken][1];
|
||||||
|
|
||||||
|
length = (q - p);
|
||||||
size = length + 16;
|
size = length + 16;
|
||||||
|
|
||||||
nameWinSCard = (char*) malloc(size);
|
nameWinSCard = (char*) malloc(size);
|
||||||
@ -391,12 +454,22 @@ char* PCSC_ConvertReaderNameToWinSCard(const char* name)
|
|||||||
if (!nameWinSCard)
|
if (!nameWinSCard)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
sprintf_s(nameWinSCard, size, "%.*s %d", length, na1, index);
|
/**
|
||||||
|
* pcsc-lite appears to use an index number based on all readers,
|
||||||
|
* while WinSCard uses an index number based on readers of the same name.
|
||||||
|
* Force an index number of 0 for now, fix later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
index = 0;
|
||||||
|
|
||||||
|
sprintf_s(nameWinSCard, size, "%.*s %d", length, p, index);
|
||||||
|
|
||||||
|
printf("Smart Card Reader Name Alias: %s -> %s\n", p, nameWinSCard);
|
||||||
|
|
||||||
return nameWinSCard;
|
return nameWinSCard;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* PCSC_ConvertReaderNamesToWinSCard(const char* names)
|
char* PCSC_ConvertReaderNamesToWinSCard(const char* names, LPDWORD pcchReaders)
|
||||||
{
|
{
|
||||||
char *p, *q;
|
char *p, *q;
|
||||||
int plen, qlen;
|
int plen, qlen;
|
||||||
@ -445,22 +518,23 @@ char* PCSC_ConvertReaderNamesToWinSCard(const char* names)
|
|||||||
CopyMemory(q, p, qlen);
|
CopyMemory(q, p, qlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
p += plen + 1;
|
|
||||||
|
|
||||||
q += qlen;
|
q += qlen;
|
||||||
*q = '\0';
|
*q = '\0';
|
||||||
q++;
|
q++;
|
||||||
|
|
||||||
|
p += plen + 1;
|
||||||
plen = strlen(p);
|
plen = strlen(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
*q = '\0';
|
*q = '\0';
|
||||||
q++;
|
q++;
|
||||||
|
|
||||||
|
*pcchReaders = (DWORD) (q - namesWinSCard);
|
||||||
|
|
||||||
return namesWinSCard;
|
return namesWinSCard;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* PCSC_ConvertReaderNamesFromWinSCard(const char* names)
|
char* PCSC_ConvertReaderNamesToPCSC(const char* names, LPDWORD pcchReaders)
|
||||||
{
|
{
|
||||||
char *p, *q;
|
char *p, *q;
|
||||||
int plen, qlen;
|
int plen, qlen;
|
||||||
@ -513,35 +587,11 @@ char* PCSC_ConvertReaderNamesFromWinSCard(const char* names)
|
|||||||
*q = '\0';
|
*q = '\0';
|
||||||
q++;
|
q++;
|
||||||
|
|
||||||
|
*pcchReaders = (DWORD) (q - namesPCSC);
|
||||||
|
|
||||||
return namesPCSC;
|
return namesPCSC;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t PCSC_MultiStringLengthA(const char* msz)
|
|
||||||
{
|
|
||||||
char* p = (char*) msz;
|
|
||||||
|
|
||||||
if (!p)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
while ((p[0] != 0) && (p[1] != 0))
|
|
||||||
p++;
|
|
||||||
|
|
||||||
return (p - msz) + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t PCSC_MultiStringLengthW(const WCHAR* msz)
|
|
||||||
{
|
|
||||||
WCHAR* p = (WCHAR*) msz;
|
|
||||||
|
|
||||||
if (!p)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
while ((p[0] != 0) && (p[1] != 0))
|
|
||||||
p++;
|
|
||||||
|
|
||||||
return (p - msz) + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PCSC_AddCardHandle(SCARDCONTEXT hContext, SCARDHANDLE hCard)
|
void PCSC_AddCardHandle(SCARDCONTEXT hContext, SCARDHANDLE hCard)
|
||||||
{
|
{
|
||||||
if (!g_CardHandles)
|
if (!g_CardHandles)
|
||||||
@ -700,6 +750,7 @@ WINSCARDAPI LONG WINAPI PCSC_SCardListReaders_Internal(SCARDCONTEXT hContext,
|
|||||||
|
|
||||||
if (g_PCSC.pfnSCardListReaders)
|
if (g_PCSC.pfnSCardListReaders)
|
||||||
{
|
{
|
||||||
|
char* mszReadersWinSCard = NULL;
|
||||||
BOOL pcchReadersWrapAlloc = FALSE;
|
BOOL pcchReadersWrapAlloc = FALSE;
|
||||||
LPSTR* pMszReaders = (LPSTR*) mszReaders;
|
LPSTR* pMszReaders = (LPSTR*) mszReaders;
|
||||||
|
|
||||||
@ -735,6 +786,19 @@ WINSCARDAPI LONG WINAPI PCSC_SCardListReaders_Internal(SCARDCONTEXT hContext,
|
|||||||
}
|
}
|
||||||
|
|
||||||
status = PCSC_MapErrorCodeToWinSCard(status);
|
status = PCSC_MapErrorCodeToWinSCard(status);
|
||||||
|
|
||||||
|
if (status == SCARD_S_SUCCESS)
|
||||||
|
{
|
||||||
|
mszReadersWinSCard = PCSC_ConvertReaderNamesToWinSCard(*pMszReaders, pcchReaders);
|
||||||
|
|
||||||
|
if (mszReadersWinSCard)
|
||||||
|
{
|
||||||
|
PCSC_SCardFreeMemory_Internal(hContext, *pMszReaders);
|
||||||
|
|
||||||
|
*pMszReaders = mszReadersWinSCard;
|
||||||
|
PCSC_AddMemoryBlock(hContext, *pMszReaders);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
@ -749,26 +813,7 @@ WINSCARDAPI LONG WINAPI PCSC_SCardListReadersA(SCARDCONTEXT hContext,
|
|||||||
|
|
||||||
if (g_PCSC.pfnSCardListReaders)
|
if (g_PCSC.pfnSCardListReaders)
|
||||||
{
|
{
|
||||||
char* mszReadersWinSCard = NULL;
|
|
||||||
LPSTR* pMszReaders = (LPSTR*) mszReaders;
|
|
||||||
|
|
||||||
status = PCSC_SCardListReaders_Internal(hContext, mszGroups, mszReaders, pcchReaders);
|
status = PCSC_SCardListReaders_Internal(hContext, mszGroups, mszReaders, pcchReaders);
|
||||||
|
|
||||||
if (!status)
|
|
||||||
{
|
|
||||||
mszReadersWinSCard = PCSC_ConvertReaderNamesToWinSCard(*pMszReaders);
|
|
||||||
|
|
||||||
if (mszReadersWinSCard)
|
|
||||||
{
|
|
||||||
PCSC_SCardFreeMemory_Internal(hContext, *pMszReaders);
|
|
||||||
|
|
||||||
*pMszReaders = mszReadersWinSCard;
|
|
||||||
*pcchReaders = PCSC_MultiStringLengthA(*pMszReaders) + 2;
|
|
||||||
PCSC_AddMemoryBlock(hContext, *pMszReaders);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
status = PCSC_MapErrorCodeToWinSCard(status);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PCSC_UnlockCardContext(hContext);
|
PCSC_UnlockCardContext(hContext);
|
||||||
@ -787,7 +832,6 @@ WINSCARDAPI LONG WINAPI PCSC_SCardListReadersW(SCARDCONTEXT hContext,
|
|||||||
{
|
{
|
||||||
LPSTR mszGroupsA = NULL;
|
LPSTR mszGroupsA = NULL;
|
||||||
LPSTR mszReadersA = NULL;
|
LPSTR mszReadersA = NULL;
|
||||||
char* mszReadersWinSCard = NULL;
|
|
||||||
LPSTR* pMszReadersA = &mszReadersA;
|
LPSTR* pMszReadersA = &mszReadersA;
|
||||||
|
|
||||||
mszGroups = NULL; /* mszGroups is not supported by pcsc-lite */
|
mszGroups = NULL; /* mszGroups is not supported by pcsc-lite */
|
||||||
@ -797,27 +841,14 @@ WINSCARDAPI LONG WINAPI PCSC_SCardListReadersW(SCARDCONTEXT hContext,
|
|||||||
|
|
||||||
status = PCSC_SCardListReaders_Internal(hContext, mszGroupsA, (LPTSTR) &mszReadersA, pcchReaders);
|
status = PCSC_SCardListReaders_Internal(hContext, mszGroupsA, (LPTSTR) &mszReadersA, pcchReaders);
|
||||||
|
|
||||||
if (!status)
|
if (status == SCARD_S_SUCCESS)
|
||||||
{
|
{
|
||||||
mszReadersWinSCard = PCSC_ConvertReaderNamesToWinSCard(mszReadersA);
|
|
||||||
|
|
||||||
if (mszReadersWinSCard)
|
|
||||||
{
|
|
||||||
PCSC_SCardFreeMemory_Internal(hContext, *pMszReadersA);
|
|
||||||
|
|
||||||
*pMszReadersA = mszReadersWinSCard;
|
|
||||||
*pcchReaders = PCSC_MultiStringLengthA(*pMszReadersA) + 2;
|
|
||||||
PCSC_AddMemoryBlock(hContext, *pMszReadersA);
|
|
||||||
}
|
|
||||||
|
|
||||||
*pcchReaders = ConvertToUnicode(CP_UTF8, 0, *pMszReadersA, *pcchReaders, (WCHAR**) mszReaders, 0);
|
*pcchReaders = ConvertToUnicode(CP_UTF8, 0, *pMszReadersA, *pcchReaders, (WCHAR**) mszReaders, 0);
|
||||||
PCSC_AddMemoryBlock(hContext, mszReaders);
|
PCSC_AddMemoryBlock(hContext, mszReaders);
|
||||||
|
|
||||||
PCSC_SCardFreeMemory_Internal(hContext, *pMszReadersA);
|
PCSC_SCardFreeMemory_Internal(hContext, *pMszReadersA);
|
||||||
}
|
}
|
||||||
|
|
||||||
status = PCSC_MapErrorCodeToWinSCard(status);
|
|
||||||
|
|
||||||
free(mszGroupsA);
|
free(mszGroupsA);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1467,14 +1498,13 @@ WINSCARDAPI LONG WINAPI PCSC_SCardStatus_Internal(SCARDHANDLE hCard,
|
|||||||
|
|
||||||
status = PCSC_MapErrorCodeToWinSCard(status);
|
status = PCSC_MapErrorCodeToWinSCard(status);
|
||||||
|
|
||||||
mszReaderNamesPCSC = PCSC_ConvertReaderNamesToWinSCard(*pMszReaderNames);
|
mszReaderNamesPCSC = PCSC_ConvertReaderNamesToPCSC(*pMszReaderNames, pcchReaderLen);
|
||||||
|
|
||||||
if (mszReaderNamesPCSC)
|
if (mszReaderNamesPCSC)
|
||||||
{
|
{
|
||||||
PCSC_SCardFreeMemory_Internal(hContext, *pMszReaderNames);
|
PCSC_SCardFreeMemory_Internal(hContext, *pMszReaderNames);
|
||||||
|
|
||||||
*pMszReaderNames = mszReaderNamesPCSC;
|
*pMszReaderNames = mszReaderNamesPCSC;
|
||||||
*pcchReaderLen = PCSC_MultiStringLengthA(*pMszReaderNames) + 2;
|
|
||||||
PCSC_AddMemoryBlock(hContext, *pMszReaderNames);
|
PCSC_AddMemoryBlock(hContext, *pMszReaderNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user