Diff

Differences From Artifact [1e8e0d368b]:

To Artifact [67b5263486]:


   839    839   
   840    840   		return(CACKEY_PCSC_E_GENERIC);
   841    841   	}
   842    842   
   843    843   	/* Connect to reader, if needed */
   844    844   	if (!slot->pcsc_card_connected) {
   845    845   		CACKEY_DEBUG_PRINTF("SCardConnect(%s) called", slot->pcsc_reader);
   846         -		scard_conn_ret = SCardConnect(*cackey_pcsc_handle, slot->pcsc_reader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &slot->pcsc_card, &protocol);
          846  +		scard_conn_ret = SCardConnect(*cackey_pcsc_handle, slot->pcsc_reader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &slot->pcsc_card, &protocol);
          847  +
          848  +		if (scard_conn_ret == SCARD_W_UNPOWERED_CARD) {
          849  +			scard_conn_ret = SCardConnect(*cackey_pcsc_handle, slot->pcsc_reader, SCARD_SHARE_DIRECT, SCARD_PROTOCOL_T0, &slot->pcsc_card, &protocol);
          850  +			scard_conn_ret = SCardReconnect(slot->pcsc_card, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, SCARD_RESET_CARD, &protocol);
          851  +		}
   847    852   
   848    853   		if (scard_conn_ret != SCARD_S_SUCCESS) {
   849    854   			CACKEY_DEBUG_PRINTF("Connection to card failed, returning in failure (SCardConnect() = %s/%li)", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(scard_conn_ret), (long) scard_conn_ret);
   850    855   
   851    856   			return(CACKEY_PCSC_E_GENERIC);
   852    857   		}
   853    858   
................................................................................
  1088   1093   
  1089   1094   		slot->transaction_depth = 0;
  1090   1095   		slot->slot_reset = 1;
  1091   1096   
  1092   1097   		if (scard_xmit_ret == SCARD_W_RESET_CARD) {
  1093   1098   			CACKEY_DEBUG_PRINTF("Reset required, please hold...");
  1094   1099   
  1095         -			scard_reconn_ret = SCardReconnect(slot->pcsc_card, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, SCARD_RESET_CARD, &protocol);
         1100  +			scard_reconn_ret = SCardReconnect(slot->pcsc_card, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, SCARD_RESET_CARD, &protocol);
  1096   1101   			if (scard_reconn_ret == SCARD_S_SUCCESS) {
  1097   1102   				/* Re-establish transaction, if it was present */
  1098   1103   				if (slot->transaction_depth > 0) {
  1099   1104   					slot->transaction_depth--;
  1100   1105   					cackey_begin_transaction(slot);
  1101   1106   				}
  1102   1107   
................................................................................
  1104   1109   
  1105   1110   				recv_len = sizeof(recv_buf);
  1106   1111   				scard_xmit_ret = SCardTransmit(slot->pcsc_card, SCARD_PCI_T0, xmit_buf, xmit_len, NULL, recv_buf, &recv_len);
  1107   1112   
  1108   1113   				if (scard_xmit_ret != SCARD_S_SUCCESS) {
  1109   1114   					CACKEY_DEBUG_PRINTF("Retransmit failed, returning in failure after disconnecting the card (SCardTransmit = %s/%li)", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(scard_xmit_ret), (long) scard_xmit_ret);
  1110   1115   
  1111         -					SCardDisconnect(slot->pcsc_card, SCARD_RESET_CARD);
         1116  +					SCardDisconnect(slot->pcsc_card, SCARD_LEAVE_CARD);
  1112   1117   					slot->pcsc_card_connected = 0;
  1113   1118   
  1114   1119   					/* End Smartcard Transaction */
  1115   1120   					slot->transaction_depth = 1;
  1116   1121   					cackey_end_transaction(slot);
  1117   1122   
  1118   1123   					return(CACKEY_PCSC_E_TOKENABSENT);
  1119   1124   				}
  1120   1125   			} else {
  1121   1126   				CACKEY_DEBUG_PRINTF("Disconnecting card");
  1122   1127   
  1123         -				SCardDisconnect(slot->pcsc_card, SCARD_RESET_CARD);
         1128  +				SCardDisconnect(slot->pcsc_card, SCARD_LEAVE_CARD);
  1124   1129   				slot->pcsc_card_connected = 0;
  1125   1130   
  1126   1131   				/* End Smartcard Transaction */
  1127   1132   				slot->transaction_depth = 1;
  1128   1133   				cackey_end_transaction(slot);
  1129   1134   
  1130   1135   				CACKEY_DEBUG_PRINTF("Returning in failure");
  1131   1136   				return(CACKEY_PCSC_E_TOKENABSENT);
  1132   1137   			}
  1133   1138   		} else {
  1134   1139   			CACKEY_DEBUG_PRINTF("Disconnecting card");
  1135   1140   
  1136         -			SCardDisconnect(slot->pcsc_card, SCARD_RESET_CARD);
         1141  +			SCardDisconnect(slot->pcsc_card, SCARD_LEAVE_CARD);
  1137   1142   			slot->pcsc_card_connected = 0;
  1138   1143   
  1139   1144   			/* End Smartcard Transaction */
  1140   1145   			slot->transaction_depth = 1;
  1141   1146   			cackey_end_transaction(slot);
  1142   1147   
  1143   1148   			CACKEY_DEBUG_PRINTF("Returning in failure");
................................................................................
  3132   3137   		CACKEY_DEBUG_PRINTF("Connection to PC/SC failed, assuming no slots");
  3133   3138   
  3134   3139   		slot_count = 0;
  3135   3140   	} else {
  3136   3141   		pcsc_readers_len = 0;
  3137   3142   
  3138   3143   		scard_listreaders_ret = SCardListReaders(*cackey_pcsc_handle, NULL, NULL, &pcsc_readers_len);
         3144  +
         3145  +		if (scard_listreaders_ret == SCARD_F_COMM_ERROR) {
         3146  +			CACKEY_DEBUG_PRINTF("Error. SCardListReaders() returned SCARD_F_COMM_ERROR, assuming Connection to PC/SC went away. Reconnecting.");
         3147  +
         3148  +			cackey_pcsc_disconnect();
         3149  +			cackey_pcsc_connect();
         3150  +
         3151  +			CACKEY_DEBUG_PRINTF("Trying SCardListReaders() again");
         3152  +			scard_listreaders_ret = SCardListReaders(*cackey_pcsc_handle, NULL, NULL, &pcsc_readers_len);
         3153  +		}
         3154  +
  3139   3155   		if (scard_listreaders_ret == SCARD_S_SUCCESS && pcsc_readers_len != 0) {
  3140   3156   			pcsc_readers = malloc(pcsc_readers_len);
  3141   3157   			pcsc_readers_s = pcsc_readers;
  3142   3158   
  3143   3159   			scard_listreaders_ret = SCardListReaders(*cackey_pcsc_handle, NULL, pcsc_readers, &pcsc_readers_len);
  3144   3160   			if (scard_listreaders_ret == SCARD_S_SUCCESS) {
  3145   3161   				pcsc_readers_e = pcsc_readers + pcsc_readers_len;