@@ -84,7 +84,7 @@ static std::string INSTRUCTION_FILE = "Instructions.txt";
8484// The one and only CWinscardApp object
8585CWinscardApp theApp;
8686
87- #define REMOTE_SOCKET_TIMEOUT 5
87+ #define REMOTE_SOCKET_TIMEOUT 20
8888#define REMOTE_SOCKET_LONG_TIMEOUT 20
8989static string_type REMOTE_SOCKET_ENDSEQ = _CONV(" @@" );
9090
@@ -99,8 +99,8 @@ BYTE GET_APDU1[] = { 0x00, 0xC0, 0x00, 0x00 };
9999BYTE GET_APDU2[] = { 0xC0 , 0xC0 , 0x00 , 0x00 };
100100
101101// #define VIRT_READER_NAME "VirtOpenPGP"
102- #define VIRT_READER_NAME " Simona /111.222.123.033@07"
103- #define VIRTUAL_READERS_LEN strlen (VIRT_READER_NAME)
102+ // #define VIRT_READER_NAME "Simona /111.222.123.033@07"
103+ // #define VIRTUAL_READERS_LEN strlen(VIRT_READER_NAME)
104104
105105#define CMD_APDU " APDU"
106106#define CMD_RESET " RESET"
@@ -853,17 +853,47 @@ SCard LONG STDCALL SCardListReaders(
853853 // NO BUFFER IS SUPPLIED
854854
855855 // OBTAIN REQUIRED LENGTH FOR REAL READERS
856- if ((status = (*Original_SCardListReaders)(hContext, mszGroups, NULL , pcchReaders)) == SCARD_S_SUCCESS) {
856+ status = (*Original_SCardListReaders)(hContext, mszGroups, NULL , pcchReaders);
857+ // Supress error when virtual readers are set
858+ if (status == SCARD_E_NO_READERS_AVAILABLE && theApp.m_winscardConfig .sVIRTUAL_READERS .length () > 0 ) {
859+ *pcchReaders = 0 ;
860+ status = SCARD_S_SUCCESS;
861+ }
862+
863+ if (status == SCARD_S_SUCCESS) {
857864 // ALLOCATE OWN BUFFER FOR REAL AND VIRTUAL READERS
858- DWORD newLen = (DWORD)(*pcchReaders + VIRTUAL_READERS_LEN + 2 );
865+ DWORD newLen = (DWORD)(*pcchReaders + theApp. m_winscardConfig . sVIRTUAL_READERS . length () + 2 );
859866 char * readers = new char [newLen];
860867 memset (readers, 0 , newLen);
861868 *pcchReaders = newLen;
862- if ((status = (*Original_SCardListReaders)(hContext, mszGroups, readers, pcchReaders)) == SCARD_S_SUCCESS) {
863- // COPY NAME OF VIRTUAL READERS TO END
864- memcpy (readers + *pcchReaders, VIRT_READER_NAME, strlen (VIRT_READER_NAME));
869+ status = (*Original_SCardListReaders)(hContext, mszGroups, readers, pcchReaders);
870+
871+
872+ if (status == SCARD_E_NO_READERS_AVAILABLE) {
873+ // No real readers are available. Check if virtual readers are supplied
874+ if (theApp.m_winscardConfig .sVIRTUAL_READERS .length () > 0 ) {
875+ LogDebugString (string_format (_CONV (" No real cards available, but virtual readers specified => continuing only with virtual readers.\n " )));
876+ // Virtual readers are required => continue as OK (only virtual will be returned)
877+ status = SCARD_S_SUCCESS;
878+ *pcchReaders = 0 ;
879+ }
880+ else {
881+ // No virtual readers specified => return SCARD_E_NO_READERS_AVAILABLE error
882+ }
883+ }
884+
885+ if (status == SCARD_S_SUCCESS) {
886+ // COPY NAME OF VIRTUAL READERS TO THE END
887+ char * virtReadersPtr = readers + *pcchReaders;
888+ memcpy (virtReadersPtr, theApp.m_winscardConfig .sVIRTUAL_READERS .c_str (), theApp.m_winscardConfig .sVIRTUAL_READERS .length ());
889+ // Virtual readers are separated by ; => change to ';' to '\0')
890+ for (size_t i = 0 ; i < theApp.m_winscardConfig .sVIRTUAL_READERS .length () + 1 ; i++) {
891+ if (virtReadersPtr[i] == ' ,' ) {
892+ virtReadersPtr[i] = ' \0 ' ;
893+ }
894+ }
865895 // ADD TRAILING ZERO
866- *pcchReaders += (DWORD)strlen (VIRT_READER_NAME ) + 1 ;
896+ *pcchReaders += (DWORD) theApp. m_winscardConfig . sVIRTUAL_READERS . length ( ) + 1 ;
867897 readers[*pcchReaders - 1 ] = 0 ;
868898 // CAST mszReaders TO char** IS NECESSARY TO CORRECTLY PROPAGATE ALLOCATED BUFFER
869899 char ** temp = (char **)mszReaders;
@@ -878,25 +908,67 @@ SCard LONG STDCALL SCardListReaders(
878908 // BUFFER SUPPLIED
879909 // OBTAIN REQUIRED LENGTH FOR REAL READERS
880910 DWORD realLen = *pcchReaders;
881- if ((status = (*Original_SCardListReaders)(hContext, mszGroups, NULL , &realLen)) == SCARD_S_SUCCESS) {
882- if ((realLen + VIRTUAL_READERS_LEN > *pcchReaders) || (mszReaders == NULL )) {
911+ status = (*Original_SCardListReaders)(hContext, mszGroups, NULL , &realLen);
912+
913+ // Supress error when virtual readers are set
914+ if (status == SCARD_E_NO_READERS_AVAILABLE && theApp.m_winscardConfig .sVIRTUAL_READERS .length () > 0 ) {
915+ realLen = 0 ;
916+ status = SCARD_S_SUCCESS;
917+ }
918+
919+ if (status == SCARD_S_SUCCESS) {
920+ if ((realLen + theApp.m_winscardConfig .sVIRTUAL_READERS .length () > *pcchReaders) || (mszReaders == NULL )) {
883921 // SUPPLIED BUFFER IS NOT LARGE ENOUGHT
884- *pcchReaders = (DWORD) (realLen + VIRTUAL_READERS_LEN );
922+ *pcchReaders = (DWORD) (realLen + theApp. m_winscardConfig . sVIRTUAL_READERS . length () );
885923 if (mszReaders != NULL ) status = SCARD_E_INSUFFICIENT_BUFFER;
886924 }
887925 else {
888926 // SUPPLIED BUFFER IS OK, COPY REAL AND VIRTUAL READERS
927+ memset (mszReaders, 0 , *pcchReaders);
889928 realLen = *pcchReaders;
890- if ((status = (*Original_SCardListReaders)(hContext, mszGroups, mszReaders, &realLen)) == SCARD_S_SUCCESS) {
929+ status = (*Original_SCardListReaders)(hContext, mszGroups, mszReaders, &realLen);
930+ if (status == SCARD_E_NO_READERS_AVAILABLE) {
931+ // No real readers are available. Check if virtual readers are supplied
932+ if (theApp.m_winscardConfig .sVIRTUAL_READERS .length () > 0 ) {
933+ LogDebugString (string_format (_CONV (" No real cards available, but virtual readers specified => continuing only with virtual readers.\n " )));
934+ // Virtual readers are required => continue as OK (only virtual will be returned)
935+ status = SCARD_S_SUCCESS;
936+ realLen = 0 ;
937+ }
938+ else {
939+ // No virtual readers specified => return SCARD_E_NO_READERS_AVAILABLE error
940+ }
941+ }
942+ if (status == SCARD_S_SUCCESS) {
891943 *pcchReaders = realLen;
892944
893- // ADD VIRTUAL READER
894- // COPY NAME OF VIRTUAL READERS TO END
895- memcpy (mszReaders + realLen, VIRT_READER_NAME, strlen (VIRT_READER_NAME));
896- *pcchReaders = (DWORD) (realLen + strlen (VIRT_READER_NAME) + 1 );
897- // ADD TRAILING ZERO
945+ if (theApp.m_winscardConfig .sVIRTUAL_READERS .length () > 0 ) {
946+ // ADD VIRTUAL READER
947+ // COPY NAME OF VIRTUAL READERS TO END
948+ char * virtReadersPtr = mszReaders;
949+ if (realLen > 0 ) { // Jump right after real readers
950+ virtReadersPtr += realLen - 1 ;
951+ }
952+ memcpy (virtReadersPtr, theApp.m_winscardConfig .sVIRTUAL_READERS .c_str (), theApp.m_winscardConfig .sVIRTUAL_READERS .length ());
953+ // Virtual readers are separated by ; => change to ';' to '\0')
954+ for (size_t i = 0 ; i < theApp.m_winscardConfig .sVIRTUAL_READERS .length () + 1 ; i++) {
955+ if (virtReadersPtr[i] == ' ,' ) {
956+ virtReadersPtr[i] = ' \0 ' ;
957+ }
958+ }
959+ // If no real readers were present, add two trailing zeroes, one otherwise
960+ if (realLen == 0 ) {
961+ *pcchReaders = (DWORD)(theApp.m_winscardConfig .sVIRTUAL_READERS .length () + 2 );
962+ }
963+ else {
964+ *pcchReaders = (DWORD)(realLen + theApp.m_winscardConfig .sVIRTUAL_READERS .length () + 1 );
965+ }
966+ }
967+ else { *pcchReaders = realLen; }
968+
969+ // ADD TWO TRAILING ZEROES
970+ mszReaders[*pcchReaders - 2 ] = 0 ;
898971 mszReaders[*pcchReaders - 1 ] = 0 ;
899- /* */
900972 CCommonFnc::String_ParseNullSeparatedArray ((BYTE*)mszReaders, *pcchReaders - 1 , &readersList);
901973 }
902974 }
@@ -1060,17 +1132,20 @@ SCard LONG STDCALL SCardListReadersW(
10601132 // OBTAIN REQUIRED LENGTH FOR REAL READERS
10611133 if ((status = (*Original_SCardListReadersW)(hContext, mszGroups, NULL , pcchReaders)) == SCARD_S_SUCCESS) {
10621134 // ALLOCATE OWN BUFFER FOR REAL AND VIRTUAL READERS
1063- DWORD newLen = (DWORD) (*pcchReaders + VIRTUAL_READERS_LEN );
1135+ DWORD newLen = (DWORD) (*pcchReaders + theApp. m_winscardConfig . sVIRTUAL_READERS . length () );
10641136 WCHAR* readers = new WCHAR[newLen];
10651137 memset (readers, 0 , newLen * sizeof (WCHAR));
10661138 *pcchReaders = newLen;
10671139 if ((status = (*Original_SCardListReadersW)(hContext, mszGroups, readers, pcchReaders)) == SCARD_S_SUCCESS) {
10681140 // COPY NAME OF VIRTUAL READERS TO END
1069- for (DWORD i = 0 ; i < strlen (VIRT_READER_NAME) + 1 ; i++) {
1070- readers[i + *pcchReaders] = VIRT_READER_NAME[i];
1141+ for (DWORD i = 0 ; i < theApp.m_winscardConfig .sVIRTUAL_READERS .length () + 1 ; i++) {
1142+ readers[i + *pcchReaders] = theApp.m_winscardConfig .sVIRTUAL_READERS .at (i);
1143+ if (readers[i + *pcchReaders] == L' ,' ) {
1144+ readers[i + *pcchReaders] = L' \0 ' ;
1145+ }
10711146 }
10721147 // ADD TRAILING ZERO
1073- *pcchReaders += (DWORD)strlen (VIRT_READER_NAME ) + 1 ;
1148+ *pcchReaders += (DWORD) theApp. m_winscardConfig . sVIRTUAL_READERS . length ( ) + 1 ;
10741149 readers[*pcchReaders - 1 ] = 0 ;
10751150 // CAST mszReaders TO char** IS NECESSARY TO CORRECTLY PROPAGATE ALLOCATED BUFFER
10761151 WCHAR** temp = (WCHAR**)mszReaders;
@@ -1086,25 +1161,29 @@ SCard LONG STDCALL SCardListReadersW(
10861161 // OBTAIN REQUIRED LENGTH FOR REAL READERS
10871162 DWORD realLen = *pcchReaders;
10881163 if ((status = (*Original_SCardListReadersW)(hContext, mszGroups, NULL , &realLen)) == SCARD_S_SUCCESS) {
1089- if ((realLen + VIRTUAL_READERS_LEN > *pcchReaders) || (mszReaders == NULL )) {
1164+ if ((realLen + theApp. m_winscardConfig . sVIRTUAL_READERS . length () > *pcchReaders) || (mszReaders == NULL )) {
10901165 // SUPPLIED BUFFER IS NOT LARGE ENOUGHT
1091- *pcchReaders = (DWORD) (realLen + VIRTUAL_READERS_LEN );
1166+ *pcchReaders = (DWORD) (realLen + theApp. m_winscardConfig . sVIRTUAL_READERS . length () );
10921167 if (mszReaders != NULL ) status = SCARD_E_INSUFFICIENT_BUFFER;
10931168 }
10941169 else {
10951170 // SUPPLIED BUFFER IS OK, COPY REAL AND VIRTUAL READERS
1096- realLen = *pcchReaders;
1171+ realLen = *pcchReaders - 1 ;
10971172 memset (mszReaders, 0 , *pcchReaders * sizeof (WCHAR));
10981173 if ((status = (*Original_SCardListReadersW)(hContext, mszGroups, mszReaders, &realLen)) == SCARD_S_SUCCESS) {
10991174 // COPY NAME OF VIRTUAL READERS TO END (IF USED)
1100- if (strlen (VIRT_READER_NAME) > 0 ) {
1101- for (DWORD i = 0 ; i < strlen (VIRT_READER_NAME) + 1 ; i++) {
1102- mszReaders[i + realLen] = VIRT_READER_NAME[i];
1175+ if (theApp.m_winscardConfig .sVIRTUAL_READERS .length () > 0 ) {
1176+ for (DWORD i = 0 ; i < theApp.m_winscardConfig .sVIRTUAL_READERS .length () + 1 ; i++) {
1177+ mszReaders[i + realLen] = theApp.m_winscardConfig .sVIRTUAL_READERS .at (i);
1178+ if (mszReaders[i + realLen] == L' ,' ) {
1179+ mszReaders[i + realLen] = L' \0 ' ;
1180+ }
11031181 }
1104- *pcchReaders = (DWORD)(realLen + strlen (VIRT_READER_NAME ) + 1 );
1182+ *pcchReaders = (DWORD)(realLen + theApp. m_winscardConfig . sVIRTUAL_READERS . length ( ) + 1 );
11051183 }
11061184 else { *pcchReaders = realLen; }
1107- // ADD TRAILING ZERO
1185+ // ADD TWO TRAILING ZEROES
1186+ mszReaders[*pcchReaders - 2 ] = 0 ;
11081187 mszReaders[*pcchReaders - 1 ] = 0 ;
11091188
11101189 CCommonFnc::String_ParseNullSeparatedArray (mszReaders, *pcchReaders, &readersList);
@@ -2933,14 +3012,14 @@ int CWinscardApp::Remote_Connect(REMOTE_CONFIG* pRemoteConfig) {
29333012 LogDebugString (message);
29343013 pRemoteConfig->pSocket = new SocketClient (sIP , type_to_int (pRemoteConfig->port .c_str (), NULL , 10 ));
29353014 if (pRemoteConfig->pSocket != NULL ) {
2936- LogDebugString (_CONV (" success" ), false );
3015+ LogDebugString (_CONV (" success\n " ), false );
29373016 }
29383017 else {
2939- LogDebugString (_CONV (" failed" ), false );
3018+ LogDebugString (_CONV (" failed\n " ), false );
29403019 }
29413020 }
29423021 catch (std::string error) {
2943- message = string_format (_CONV (" Failed to connect to %s:%s (error: %s)\n " ), pRemoteConfig->IP .c_str (), pRemoteConfig->port .c_str (), error);
3022+ message = string_format (_CONV (" Failed to connect to %s:%s (error: %s)\n " ), pRemoteConfig->IP .c_str (), pRemoteConfig->port .c_str (), error. c_str () );
29443023 LogDebugString (message, false );
29453024 }
29463025 catch (...) {
@@ -3069,7 +3148,8 @@ Remote card protocol
30693148 all other lines not starting with > or # are ignored
30703149*/
30713150string_type Remote_FormatRequest (string_type targetReader, DWORD uniqueCmdID, string_type command, string_type commandData, string_type notes, string_type lineSeparator) {
3072- return string_format (" >%s%s>%d%s%s%s%s%s%s" , targetReader.c_str (), lineSeparator.c_str (), uniqueCmdID, CMD_SEPARATOR, command.c_str (), CMD_SEPARATOR, commandData.c_str (), lineSeparator.c_str (), notes.c_str ());
3151+ // return string_format(">%s%s>%d%s%s%s%s%s%s", targetReader.c_str(), lineSeparator.c_str(), uniqueCmdID, CMD_SEPARATOR, command.c_str(), CMD_SEPARATOR, commandData.c_str(), lineSeparator.c_str(), notes.c_str());
3152+ return string_format (" >%s%s\n >%d%s%s%s%s%s%s" , targetReader.c_str (), lineSeparator.c_str (), uniqueCmdID, CMD_SEPARATOR, command.c_str (), CMD_SEPARATOR, commandData.c_str (), lineSeparator.c_str (), notes.c_str ());
30733153}
30743154
30753155#if defined (_WIN32)
@@ -3126,7 +3206,7 @@ LONG CWinscardApp::Remote_ParseResponse(string_type rawResponse, DWORD expectedC
31263206
31273207 size_t pos = 0 ;
31283208 if (rawResponse.at (pos) != ' >' ) {
3129- LogWinscardRules (" '>'was expected at begin" );
3209+ LogWinscardRules (" '>'was expected at begin\n " );
31303210 status = SCARD_F_COMM_ERROR;
31313211 }
31323212 pos++;
@@ -3135,7 +3215,7 @@ LONG CWinscardApp::Remote_ParseResponse(string_type rawResponse, DWORD expectedC
31353215 size_t pos2 = rawResponse.find (CMD_SEPARATOR);
31363216 string_type uniqueCmdID = rawResponse.substr (pos, pos2 - 1 );
31373217 if (expectedCommandID != atoi (uniqueCmdID.c_str ())) {
3138- LogWinscardRules (" Unexpected commandID in response" );
3218+ LogWinscardRules (" Unexpected commandID in response\n " );
31393219 status = SCARD_F_COMM_ERROR;
31403220 }
31413221 pos = pos2 + 1 ;
@@ -3274,6 +3354,12 @@ int CWinscardApp::LoadRule(const char_type* section_name, dictionary* dict/*stri
32743354 {
32753355 m_winscardConfig.sREADER_ORDERED_FIRST = char_value;
32763356 }
3357+ type_copy (sec_and_key, section_name);
3358+ char_value = iniparser_getstring (dict, type_cat (sec_and_key, _CONV (" :VIRTUAL_READERS" )), " " );
3359+ if (type_length (char_value) != 0 )
3360+ {
3361+ m_winscardConfig.sVIRTUAL_READERS = char_value;
3362+ }
32773363 }
32783364
32793365#if defined (_WIN32)
0 commit comments