return true;
}
+// -- cSmartCardSlotCCID -------------------------------------------------------
+
+#ifdef WITH_PCSC
+#include <winscard.h>
+
+class cSmartCardSlotCCID : public cSmartCardSlot {
+private:
+ SCARDCONTEXT hContext;
+ SCARDHANDLE hCard;
+ DWORD dwActiveProtocol, dwProtocol;
+ DWORD dwState, dwReaderLen;
+ bool needsReOpen;
+ //
+ int Transmit(const unsigned char *request, int requestlen, unsigned char *answer, int answerlen);
+protected:
+ virtual bool DeviceOpen(const char *cfg);
+ virtual void DeviceClose(void);
+ virtual bool DeviceSetMode(int mode, int baud);
+ virtual int DeviceRead(unsigned char *mem, int len, int timeout, int initialTimeout=0) { return -1; }
+ virtual int DeviceWrite(const unsigned char *mem, int len, int delay=0) { return -1; }
+ virtual void DeviceToggleReset(void) {}
+ virtual bool DevicePTS(void) { return false; }
+ virtual bool DeviceIsInserted(void);
+ //
+ virtual bool Reset(void);
+public:
+ virtual bool IsoRead(const unsigned char *cmd, unsigned char *data);
+ virtual bool IsoWrite(const unsigned char *cmd, const unsigned char *data);
+ virtual int RawRead(unsigned char *data, int len, int to=0) { return -1; }
+ virtual int RawWrite(const unsigned char *data, int len) { return -1; }
+ };
+
+static cSmartCardSlotLinkReg<cSmartCardSlotCCID> __scs_ccid("ccid");
+
+bool cSmartCardSlotCCID::DeviceOpen(const char *cfg)
+{
+ if(sscanf(cfg,"%255[^:]",devName)==1) {
+ LONG rv=SCardEstablishContext(SCARD_SCOPE_SYSTEM,NULL,NULL,&hContext);
+ PRINTF(L_CORE_SC,"%s: establish Context: %ld:%s",devName,rv,pcsc_stringify_error(rv));
+ DWORD protocol=SCARD_PROTOCOL_T0|SCARD_PROTOCOL_T1;
+ rv=SCardConnect(hContext,devName,SCARD_SHARE_SHARED,protocol,&hCard,&dwActiveProtocol);
+ dwProtocol=dwActiveProtocol;
+ PRINTF(L_CORE_SC,"%s: connect: %ld:%s",devName,rv,pcsc_stringify_error(rv));
+ needsReOpen=false;
+ return true;
+ }
+ else PRINTF(L_GEN_ERROR,"bad parameter for cardslot type 'ccid'");
+ return false;
+}
+
+void cSmartCardSlotCCID::DeviceClose(void)
+{
+ SCardDisconnect(hCard,SCARD_RESET_CARD);
+ SCardReleaseContext(hContext);
+}
+
+bool cSmartCardSlotCCID::DeviceSetMode(int mode, int baud)
+{
+ currMode=mode;
+ return true;
+}
+
+bool cSmartCardSlotCCID::DeviceIsInserted(void)
+{
+ BYTE pbAtr[MAX_ATR_SIZE];
+ DWORD dwAtrLen=sizeof(pbAtr);
+ LONG rv=SCardStatus(hCard,NULL,&dwReaderLen,&dwState,&dwProtocol,pbAtr,&dwAtrLen);
+ if(rv==SCARD_S_SUCCESS && (dwState&SCARD_NEGOTIABLE)) return true;
+ needsReOpen=true;
+ return false;
+}
+
+bool cSmartCardSlotCCID::Reset(void)
+{
+ PRINTF(L_CORE_SC,"%d: reseting card (sermode %s)",slotnum,serModes[DeviceCurrentMode()]);
+ if(needsReOpen) { DeviceClose(); DeviceOpen(0); }
+ LONG rv=SCardReconnect(hCard,SCARD_SHARE_EXCLUSIVE,dwProtocol,SCARD_RESET_CARD,&dwActiveProtocol);
+ if(rv!=SCARD_S_SUCCESS) {
+ PRINTF(L_CORE_SC,"%d: reset failed: %lx:%sn",slotnum,rv,pcsc_stringify_error(rv));
+ return false;
+ }
+ DWORD dwAtrLen=sizeof(atr.atr);
+ rv=SCardStatus(hCard,NULL,&dwReaderLen,&dwState,&dwProtocol,atr.atr,&dwAtrLen);
+ if(rv==SCARD_S_SUCCESS) {
+ atr.atrLen=dwAtrLen;
+ LDUMP(L_CORE_SC,atr.atr,dwAtrLen,"%d: <- ATR len=%ld:",slotnum,dwAtrLen);
+ return true;
+ }
+ return false;
+}
+
+int cSmartCardSlotCCID::Transmit(const unsigned char *request, int requestlen, unsigned char *answer, int answerlen)
+{
+ SCARD_IO_REQUEST pioRecvPci, pioSendPci;
+ switch (dwProtocol) {
+ case SCARD_PROTOCOL_T0:
+ case SCARD_PROTOCOL_T1:
+ pioSendPci.dwProtocol=dwProtocol;
+ pioSendPci.cbPciLength=sizeof(pioSendPci);
+ pioRecvPci.dwProtocol=dwProtocol;
+ pioRecvPci.cbPciLength=sizeof(pioRecvPci);
+ break;
+ default:
+ PRINTF(L_CORE_SC,"%d: protocol failure: %ld",slotnum,dwProtocol);
+ return 0;
+ }
+ DWORD answlen=answerlen;
+ DWORD rv=SCardTransmit(hCard,&pioSendPci,(LPCBYTE)request,(DWORD)requestlen,&pioRecvPci,(LPBYTE)answer,&answlen);
+ if(rv!=SCARD_S_SUCCESS) {
+ PRINTF(L_CORE_SC, "%d: transmit failed: %0lx:%s\n",slotnum,rv,pcsc_stringify_error(rv));
+ return -1;
+ }
+ return answlen;
+}
+
+bool cSmartCardSlotCCID::IsoRead(const unsigned char *cmd, unsigned char *data)
+{
+ LDUMP(L_CORE_SC,cmd,CMD_LEN,"%d: -> INS:",slotnum);
+ int restlen=Transmit(cmd,CMD_LEN,data,MAX_LEN);
+ if(restlen<2) return Test(false);
+ sb[0]=data[restlen-2];
+ sb[1]=data[restlen-1];
+ LDUMP(L_CORE_SC,sb,2,"%d: <- SB: ",slotnum);
+ LDUMP(L_CORE_SC,data,restlen-2,"%d: <- DATA:",slotnum);
+ return true;
+}
+
+bool cSmartCardSlotCCID::IsoWrite(const unsigned char *cmd, const unsigned char *data)
+{
+ LDUMP(L_CORE_SC,cmd,CMD_LEN,"%d: -> INS:",slotnum);
+ LDUMP(L_CORE_SC,data,cmd[LEN_IDX],"%d: -> DATA:",slotnum);
+ unsigned char sendbuf[MAX_LEN+CMD_LEN], recvbuf[MAX_LEN];
+ memcpy(sendbuf,cmd,CMD_LEN);
+ memcpy(sendbuf+CMD_LEN,data,sendbuf[LEN_IDX]);
+ int restlen=Transmit(sendbuf,CMD_LEN+sendbuf[LEN_IDX],recvbuf,MAX_LEN);
+ if(restlen<2) return Test(false);
+ sb[0]=recvbuf[restlen-2];
+ sb[1]=recvbuf[restlen-1];
+ LDUMP(L_CORE_SC,sb,2,"%d: <- SB: ",slotnum);
+ return true;
+}
+
+#endif //WITH_PCSC
+
// -- cSmartCardSlotEmuGeneric -------------------------------------------------
#ifdef CARD_EMU