diff --git a/Release_bins/Winscard_32b_v2019.09.11.zip b/Release_bins/Winscard_32b_v2019.09.11.zip new file mode 100644 index 0000000..9d2887e Binary files /dev/null and b/Release_bins/Winscard_32b_v2019.09.11.zip differ diff --git a/Release_bins/Winscard_64b_v2019.09.11.zip b/Release_bins/Winscard_64b_v2019.09.11.zip new file mode 100644 index 0000000..86535d9 Binary files /dev/null and b/Release_bins/Winscard_64b_v2019.09.11.zip differ diff --git a/Winscard/Winscard.cpp b/Winscard/Winscard.cpp index baf3794..6477689 100644 --- a/Winscard/Winscard.cpp +++ b/Winscard/Winscard.cpp @@ -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 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 } @@ -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); @@ -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; + } + else { + // No virtual readers specified => return SCARD_E_NO_READERS_AVAILABLE error } - // 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); } + + 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; @@ -1172,7 +1214,21 @@ 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; @@ -1180,17 +1236,17 @@ SCard LONG STDCALL SCardListReadersW( 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); } } @@ -1937,23 +1993,38 @@ SCard LONG STDCALL SCardGetStatusChangeW( IN OUT LPSCARD_READERSTATEW rgReaderStates, IN DWORD cReaders ) { - LONG status = SCARD_S_SUCCESS; + LogWinscardRules(_CONV("SCardGetStatusChangeW called\n")); + + char readerNameA[1000]; + memset(readerNameA, 0, sizeof(readerNameA)); // Convert wchar to ascii - std::wstring_convert> convertor; - 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];} - LogWinscardRules(_CONV("SCardGetStatusChangeW called\n")); string_type message = string_format(_CONV("-> rgReaderStates.szReader: %s\n"), readerNameA); LogWinscardRules(message); + + LONG status = SCARD_S_SUCCESS; if (theApp.IsRemoteReader(readerNameA)) { status = SCARD_S_SUCCESS; + rgReaderStates->dwEventState = 0x00010422; + + // Set ATR based on previously retrieved value + if (theApp.remoteCardsATRMap.find(readerNameA) != theApp.remoteCardsATRMap.end()) { + string_type atr = theApp.remoteCardsATRMap[readerNameA]; + rgReaderStates->cbAtr = 0x24; + CCommonFnc::BYTE_ConvertFromHexStringToArray(atr, rgReaderStates->rgbAtr, &(rgReaderStates->cbAtr)); + } + else { + rgReaderStates->cbAtr = 0x00; + } } else { status = (*Original_SCardGetStatusChangeW)(hContext, dwTimeout, rgReaderStates, cReaders); } message = string_format(_CONV("-> return status: 0x%x\n"), status); LogWinscardRules(message); - return status; } @@ -1966,6 +2037,8 @@ SCard LONG STDCALL SCardUIDlgSelectCardA( ) { LogWinscardRules(_CONV("SCardUIDlgSelectCardA called\n")); return (*Original_SCardUIDlgSelectCardA)(a); + + } diff --git a/Winscard/Winscard.rc b/Winscard/Winscard.rc index ea83711..f31cf24 100644 --- a/Winscard/Winscard.rc +++ b/Winscard/Winscard.rc @@ -12,90 +12,103 @@ ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// Czech (Czech Republic) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CSY) +LANGUAGE LANG_CZECH, SUBLANG_DEFAULT +#pragma code_page(1250) + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 2019,9,11,1 + PRODUCTVERSION 2019,9,11,1 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904e4" + BEGIN + VALUE "CompanyName", "APDUPlay" + VALUE "FileDescription", "APDUPlay stub for winscard.dll" + VALUE "FileVersion", "2019.9.11.1" + VALUE "InternalName", "Winscard.dll" + VALUE "LegalCopyright", "CRoCS MUNI" + VALUE "OriginalFilename", "Winscard.dll" + VALUE "ProductName", "APDUPlay" + VALUE "ProductVersion", "2019.9.11.1" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + END +END + +#endif // Czech (Czech Republic) resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// English (United Kingdom) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK +#pragma code_page(1252) + #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // TEXTINCLUDE // -1 TEXTINCLUDE +1 TEXTINCLUDE BEGIN "resource.h\0" END -2 TEXTINCLUDE +2 TEXTINCLUDE BEGIN "#include ""afxres.h""\n" "\0" END -3 TEXTINCLUDE +3 TEXTINCLUDE BEGIN "#define _AFX_NO_SPLITTER_RESOURCES\n" "#define _AFX_NO_OLE_RESOURCES\n" "#define _AFX_NO_TRACKER_RESOURCES\n" "#define _AFX_NO_PROPERTY_RESOURCES\n" "\n" - "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CSY)\n" - "LANGUAGE 5, 1\n" - "#pragma code_page(1250)\n" + "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CSY)\n" + "LANGUAGE 5, 1\n" + "#pragma code_page(1250)\n" "#include ""res\\Winscard.rc2"" // non-Microsoft Visual C++ edited resources\n" -#ifndef _AFXDLL - "#include ""afxres.rc"" // Standard components\n" -#endif + "#include ""afxres.rc"" // Standard components\n" "#endif\n" "\0" END -///////////////////////////////////////////////////////////////////////////// #endif // APSTUDIO_INVOKED - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CSY) -LANGUAGE 5, 1 -#pragma code_page(1250) - +#endif // English (United Kingdom) resources ///////////////////////////////////////////////////////////////////////////// -// -// Version -// -VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,0,0,1 - PRODUCTVERSION 1,0,0,1 - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x4L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904e4" - BEGIN - VALUE "CompanyName", "TODO: " - VALUE "FileDescription", "TODO: " - VALUE "FileVersion", "1.0.0.1" - VALUE "InternalName", "Winscard.dll" - VALUE "LegalCopyright", "TODO: (c) . All rights reserved." - VALUE "OriginalFilename","Winscard.dll" - VALUE "ProductName", "TODO: " - VALUE "ProductVersion", "1.0.0.1" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x0409, 1252 - END -END -#endif -#ifndef APSTUDIO_INVOKED +#ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 3 resource. @@ -108,10 +121,8 @@ END #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CSY) LANGUAGE 5, 1 #pragma code_page(1250) -#include "res\\Winscard.rc2" // non-Microsoft Visual C++ edited resources -#ifndef _AFXDLL -#include "afxres.rc" // Standard components -#endif +#include "res\Winscard.rc2" // non-Microsoft Visual C++ edited resources +#include "afxres.rc" // Standard components #endif /////////////////////////////////////////////////////////////////////////////