Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v2019.09.11 #25

Merged
merged 4 commits into from
Sep 11, 2019
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fixed bug preventing work with remote readers when no local is presen…
…t (for unicode apps)
  • Loading branch information
petrs committed Sep 11, 2019
commit c2b5674bbe974377895bc67ef165b0a48be9337d
155 changes: 112 additions & 43 deletions Winscard/Winscard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1104,10 +1104,24 @@ SCard LONG STDCALL SCardListReadersW(

// Try to read list of remote readers if required
if (theApp.m_remoteConfig.bRedirect) {
string_type readers = "";
list<string_type> remoteReaders;
if (theApp.Remote_ListReaders(&(theApp.m_remoteConfig), &remoteReaders) == SCARD_S_SUCCESS) {
// Put remote readers into list
theApp.m_winscardConfig.listVIRTUAL_READERS = remoteReaders;
theApp.remoteCardsATRMap.clear(); // Clear ATR of remote cards
// Obtain ATR for every remote reader
ls::iterator iter;
for (iter = remoteReaders.begin(); iter != remoteReaders.end(); iter++) {
string_type atr;
status = theApp.Remote_SCardConnect(&(theApp.m_remoteConfig), *iter, &atr);
if (status == SCARD_S_SUCCESS) {
theApp.remoteCardsATRMap[*iter] = atr;
}
}


// readers from cfg file
theApp.m_winscardConfig.listVIRTUAL_READERS.insert(theApp.m_winscardConfig.listVIRTUAL_READERS.begin(),
theApp.m_winscardConfig.listVIRTUAL_READERS_STATIC.begin(), theApp.m_winscardConfig.listVIRTUAL_READERS_STATIC.end()); // readers from cfg file
}
Expand All @@ -1117,8 +1131,15 @@ SCard LONG STDCALL SCardListReadersW(
// NO BUFFER IS SUPPLIED
// OBTAIN REQUIRED LENGTH FOR REAL READERS
DWORD realLen = 0;
if ((status = (*Original_SCardListReadersW)(hContext, mszGroups, NULL, &realLen)) == SCARD_S_SUCCESS) {
*pcchReaders = realLen;
status = (*Original_SCardListReadersW)(hContext, mszGroups, NULL, &realLen);
*pcchReaders = realLen;
// Supress error when virtual readers are set
if (status == SCARD_E_NO_READERS_AVAILABLE && theApp.m_winscardConfig.listVIRTUAL_READERS.size() > 0) {
*pcchReaders = 0;
status = SCARD_S_SUCCESS;
}

if (status == SCARD_S_SUCCESS) {
// ALLOCATE OWN BUFFER FOR REAL AND VIRTUAL READERS
size_t virtReadersLen = 0;
CCommonFnc::String_SerializeAsSeparatedArray(&theApp.m_winscardConfig.listVIRTUAL_READERS, L'\0', NULL, &virtReadersLen);
Expand All @@ -1127,43 +1148,64 @@ SCard LONG STDCALL SCardListReadersW(
WCHAR* readers = new WCHAR[newLen];
memset(readers, 0, newLen * sizeof(WCHAR));
*pcchReaders = newLen;
realLen = newLen;
if ((status = (*Original_SCardListReadersW)(hContext, mszGroups, readers, &realLen)) == SCARD_S_SUCCESS) {
*pcchReaders = realLen;
status = (*Original_SCardListReadersW)(hContext, mszGroups, readers, pcchReaders);


if (status == SCARD_E_NO_READERS_AVAILABLE) {
// No real readers are available. Check if virtual readers are supplied
if (theApp.m_winscardConfig.listVIRTUAL_READERS.size() > 0) {
// COPY NAME OF VIRTUAL READERS TO END
WCHAR* virtReadersPtr = readers;
if (realLen > 0) { // Jump right after real readers
virtReadersPtr += realLen - 1;
}
CCommonFnc::String_SerializeAsSeparatedArray(&theApp.m_winscardConfig.listVIRTUAL_READERS, L'\0', virtReadersPtr, &virtReadersLen);
// If no real readers were present, add two trailing zeroes, one otherwise
if (realLen == 0) {
*pcchReaders = (DWORD)(virtReadersLen + 1); // Add additional zero
}
else {
*pcchReaders = (DWORD)(realLen + virtReadersLen); // additional zero was already inserted before
}
mszReaders[*pcchReaders - 1] = 0;
LogDebugString(string_format(_CONV("No real cards available, but virtual readers specified => continuing only with virtual readers.\n")));
// Virtual readers are required => continue as OK (only virtual will be returned)
status = SCARD_S_SUCCESS;
*pcchReaders = 0;
}
// CAST mszReaders TO char** IS NECESSARY TO CORRECTLY PROPAGATE ALLOCATED BUFFER
WCHAR** temp = (WCHAR**)mszReaders;
*temp = readers;
CCommonFnc::String_ParseNullSeparatedArray(readers, *pcchReaders, &readersList);
// ADD ALLOCATED MEMORY TO LIST FOR FUTURE DEALLOCATION
theApp.m_wcharAllocatedMemoryList.push_back(readers);
else {
// No virtual readers specified => return SCARD_E_NO_READERS_AVAILABLE error
}
}

if (status == SCARD_S_SUCCESS) {
// COPY NAME OF VIRTUAL READERS TO THE END
WCHAR* virtReadersPtr = readers;
if (realLen > 0) { // Jump right after real readers
virtReadersPtr += realLen - 1;
}
CCommonFnc::String_SerializeAsSeparatedArray(&theApp.m_winscardConfig.listVIRTUAL_READERS, L'\0', virtReadersPtr, &virtReadersLen);
// If no real readers were present, add two trailing zeroes, one otherwise
if (realLen == 0) {
*pcchReaders = (DWORD)(virtReadersLen + 1); // Add additional zero
}
else {
*pcchReaders = (DWORD)(realLen + virtReadersLen); // additional zero was already inserted before
}
mszReaders[*pcchReaders - 1] = 0;
}
// CAST mszReaders TO char** IS NECESSARY TO CORRECTLY PROPAGATE ALLOCATED BUFFER
WCHAR** temp = (WCHAR**)mszReaders;
*temp = readers;
CCommonFnc::String_ParseNullSeparatedArray(readers, *pcchReaders, &readersList);
// ADD ALLOCATED MEMORY TO LIST FOR FUTURE DEALLOCATION
theApp.m_wcharAllocatedMemoryList.push_back(readers);
}
}
else {
// BUFFER SUPPLIED
// OBTAIN REQUIRED LENGTH FOR REAL READERS
DWORD realLen = *pcchReaders;
if ((status = (*Original_SCardListReadersW)(hContext, mszGroups, NULL, &realLen)) == SCARD_S_SUCCESS) {
status = (*Original_SCardListReadersW)(hContext, mszGroups, NULL, &realLen);

// Supress error when virtual readers are set
if (status == SCARD_E_NO_READERS_AVAILABLE && theApp.m_winscardConfig.listVIRTUAL_READERS.size() > 0) {
realLen = 0;
status = SCARD_S_SUCCESS;
}

if (status == SCARD_S_SUCCESS) {
size_t virtReadersLen = 0;
CCommonFnc::String_SerializeAsSeparatedArray(&theApp.m_winscardConfig.listVIRTUAL_READERS, L'\0', NULL, &virtReadersLen);

if ((realLen + virtReadersLen + 2 > *pcchReaders) || (mszReaders == NULL)) {
LogWinscardRules(_CONV("Likely dummy call to obtain required buffer length for readers\n"));
// SUPPLIED BUFFER IS NOT LARGE ENOUGHT
*pcchReaders = (DWORD)(realLen + virtReadersLen + 2);
if (mszReaders != NULL) status = SCARD_E_INSUFFICIENT_BUFFER;
Expand All @@ -1172,25 +1214,39 @@ SCard LONG STDCALL SCardListReadersW(
// SUPPLIED BUFFER IS OK, COPY REAL AND VIRTUAL READERS
realLen = *pcchReaders - 1;
memset(mszReaders, 0x00, *pcchReaders * sizeof(WCHAR));
if ((status = (*Original_SCardListReadersW)(hContext, mszGroups, mszReaders, &realLen)) == SCARD_S_SUCCESS) {
status = (*Original_SCardListReadersW)(hContext, mszGroups, mszReaders, &realLen);
if (status == SCARD_E_NO_READERS_AVAILABLE) {
// No real readers are available. Check if virtual readers are supplied
if (theApp.m_winscardConfig.listVIRTUAL_READERS.size() > 0) {
LogDebugString(string_format(_CONV("No real cards available, but virtual readers specified => continuing only with virtual readers.\n")));
// Virtual readers are required => continue as OK (only virtual will be returned)
status = SCARD_S_SUCCESS;
realLen = 0;
}
else {
// No virtual readers specified => return SCARD_E_NO_READERS_AVAILABLE error
}
}
if (status == SCARD_S_SUCCESS) {
*pcchReaders = realLen;
// COPY NAME OF VIRTUAL READERS TO END (IF USED)
if (theApp.m_winscardConfig.listVIRTUAL_READERS.size() > 0) {
WCHAR* virtReadersPtr = mszReaders;
if (realLen > 0) { // Jump right after real readers
virtReadersPtr += realLen - 1;
}
CCommonFnc::String_SerializeAsSeparatedArray(&theApp.m_winscardConfig.listVIRTUAL_READERS, L'\0', virtReadersPtr, &virtReadersLen);

// If no real readers were present, add two trailing zeroes, one otherwise
if (realLen == 0) {
*pcchReaders = (DWORD)(virtReadersLen + 1); // Add additional zero
}
else {
*pcchReaders = (DWORD)(realLen + virtReadersLen); // additional zero was already inserted before
}
mszReaders[*pcchReaders - 1] = 0;
}
else { *pcchReaders = realLen; }
// If no real readers were present, add two trailing zeroes, one otherwise
if (realLen == 0) {
*pcchReaders = (DWORD)(virtReadersLen + 1); // Add additional zero
}
else {
*pcchReaders = (DWORD)(realLen + virtReadersLen); // additional zero was already inserted before
}
mszReaders[*pcchReaders - 1] = 0;

CCommonFnc::String_ParseNullSeparatedArray(mszReaders, *pcchReaders, &readersList);
}
}
Expand Down Expand Up @@ -1938,15 +1994,26 @@ SCard LONG STDCALL SCardGetStatusChangeW(
IN DWORD cReaders
) {
LONG status = SCARD_S_SUCCESS;
char readerNameA[1000];
memset(readerNameA, 0, sizeof(readerNameA));
// Convert wchar to ascii
std::wstring_convert<std::codecvt_utf8<wchar_t>> convertor;
std::string readerNameA = convertor.to_bytes(rgReaderStates->szReader);
//std::string readerNameA = convertor.to_bytes(rgReaderStates->szReader);
int len = wcslen(rgReaderStates->szReader);
if (sizeof(readerNameA) < len) {
return SCARD_F_INTERNAL_ERROR;
}
for (int i = 0; i < len; i++) {
readerNameA[i] = (char) rgReaderStates->szReader[i];
}
//std::string readerNameA = convertor.to_bytes(rgReaderStates->szReader);

LogWinscardRules(_CONV("SCardGetStatusChangeW called\n"));
string_type message = string_format(_CONV("-> rgReaderStates.szReader: %s\n"), readerNameA);
string_type message = string_format(_CONV("-> rgReaderStates.szReader: '%s'\n"), readerNameA);
//string_type message = string_format(_CONV("-> rgReaderStates.szReader: %s\n"), rgReaderStates->szReader);
LogWinscardRules(message);
if (theApp.IsRemoteReader(readerNameA)) {
status = SCARD_S_SUCCESS;
status = SCARD_S_SUCCESS;
}
else {
status = (*Original_SCardGetStatusChangeW)(hContext, dwTimeout, rgReaderStates, cReaders);
Expand All @@ -1966,6 +2033,8 @@ SCard LONG STDCALL SCardUIDlgSelectCardA(
) {
LogWinscardRules(_CONV("SCardUIDlgSelectCardA called\n"));
return (*Original_SCardUIDlgSelectCardA)(a);


}


Expand Down Expand Up @@ -3432,8 +3501,8 @@ LONG CWinscardApp::Remote_SendRequest(REMOTE_CONFIG* pRemoteConfig, string_type
string_type l = Remote_FormatRequest(targetReader, theApp.m_remoteConfig.nextCommandID, command, commandData, "", CMD_LINE_SEPARATOR);
pRemoteConfig->pSocket->SendLine(l);
replace(l.begin(), l.end(), '\n', ' ');
//message = string_format(_CONV("::-> %s\n"), l.c_str());
message = string_format(_CONV("::-> %s %s\n"), command.c_str(), "(hidden data)");
message = string_format(_CONV("::-> %s\n"), l.c_str());
//message = string_format(_CONV("::-> %s %s\n"), command.c_str(), "(hidden data)");
LogWinscardRules(message);
if (REMOTE_APDU_RESPONSE_WAIT_TIME > 0) {
_sleep(REMOTE_APDU_RESPONSE_WAIT_TIME);
Expand All @@ -3445,8 +3514,8 @@ LONG CWinscardApp::Remote_SendRequest(REMOTE_CONFIG* pRemoteConfig, string_type
status = Remote_ParseResponse(l, theApp.m_remoteConfig.nextCommandID, pResponse);

replace(pResponse->begin(), pResponse->end(), '\n', ' ');
//message = string_format(_CONV("::<- %s\n"), pResponse->c_str());
message = string_format(_CONV("::<- %s\n"), "(hidden response)");
message = string_format(_CONV("::<- %s\n"), pResponse->c_str());
//message = string_format(_CONV("::<- %s\n"), "(hidden response)");
LogWinscardRules(message);

if (pRemoteConfig->bOpenSocketForEveryCommand) {
Expand Down