Created
October 17, 2016 19:24
-
-
Save leifj/140f9c79d99af078c5167f587cd81b69 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <winscard.h> | |
#define CHECK(f, rv) \ | |
if (SCARD_S_SUCCESS != rv) \ | |
{ \ | |
fprintf(stderr, f ": %s\n", pcsc_stringify_error(rv)); \ | |
return -1; \ | |
} | |
#define CHECK_RESPONSE(buffer, bufferLength) \ | |
if(buffer[bufferLength-2] != 0x90 || buffer[bufferLength-1] != 0x00) { \ | |
fprintf(stderr, "Invalid response!\n"); \ | |
return -2; \ | |
} | |
int main(int argc, char *argv[]) { | |
LONG rv; | |
SCARDCONTEXT hContext; | |
SCARDHANDLE hCard; | |
DWORD dwReaders, dwActiveProtocol, dwRecvLength; | |
LPTSTR mszReaders; | |
SCARD_IO_REQUEST pioSendPci; | |
BYTE pbRecvBuffer[266]; | |
unsigned int i; | |
fprintf(stderr, "Smart Card reader - terciofilho - hashtips.wordpress.com\n"); | |
BYTE cmdDefineCardType[] = { 0xFF, 0xA4, 0x00, 0x00, 0x01, 0x06 }; | |
BYTE cmdReadCard[] = { 0xFF, 0xB0, 0x00, 0x20, 0xC0 }; | |
if(argc != 3) | |
{ | |
fprintf(stderr, "Usage: %s FIRST_ADDRESS READ_LENGTH\nNo parameters provided, default values:\nFIRST_ADDRESS = 0x%X\ | |
nREAD_LENGTH = 0x%X\n", argv[0], cmdReadCard[3], cmdReadCard[4]); | |
} | |
else | |
{ | |
if(strtol(argv[2], NULL, 16) > 256) | |
{ | |
fprintf(stderr, "Invalid READ_LENGTH. Must be < 256.\n"); | |
return -3; | |
} | |
cmdReadCard[3] = strtol(argv[1], NULL, 16); | |
cmdReadCard[4] = strtol(argv[2], NULL, 16); | |
fprintf(stderr, "FIRST_ADDRESS = 0x%02x\nREAD_LENGTH = 0x%02x\n", cmdReadCard[3], cmdReadCard[4]); | |
} | |
rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext); | |
CHECK("SCardEstablishContext", rv); | |
dwReaders = SCARD_AUTOALLOCATE; | |
rv = SCardListReaders(hContext, NULL, (LPTSTR)&mszReaders, &dwReaders); | |
CHECK("SCardListReaders", rv) | |
fprintf(stderr, "Reader name: %s\n", mszReaders); | |
rv = SCardConnect(hContext, mszReaders, SCARD_SHARE_DIRECT, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol); | |
//rv = SCardConnect(hContext, mszReaders, SCARD_SHARE_EXCLUSIVE, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1 | SCARD_PROTOCOL_RAW, &hCard, &dwActiveProtocol); | |
CHECK("SCardConnect", rv) | |
switch(dwActiveProtocol) | |
{ | |
case SCARD_PROTOCOL_T0: | |
fprintf(stderr, "T0\n"); | |
pioSendPci = *SCARD_PCI_T0; | |
break; | |
case SCARD_PROTOCOL_T1: | |
fprintf(stderr, "T1\n"); | |
pioSendPci = *SCARD_PCI_T1; | |
break; | |
case SCARD_PROTOCOL_RAW: | |
fprintf(stderr, "RAW\n"); | |
pioSendPci = *SCARD_PCI_RAW; | |
break; | |
default: | |
fprintf(stderr, "active protocol: %lu", dwActiveProtocol); | |
break; | |
} | |
dwRecvLength = sizeof(pbRecvBuffer); | |
rv = SCardTransmit(hCard, &pioSendPci, cmdDefineCardType, sizeof(cmdDefineCardType), NULL, pbRecvBuffer, &dwRecvLength); | |
CHECK("SCardTransmit (define card type)", rv) | |
CHECK_RESPONSE(pbRecvBuffer, dwRecvLength); | |
dwRecvLength = sizeof(pbRecvBuffer); | |
rv = SCardTransmit(hCard, &pioSendPci, cmdReadCard, sizeof(cmdReadCard), NULL, pbRecvBuffer, &dwRecvLength); | |
CHECK("SCardTransmit (read card)", rv) | |
CHECK_RESPONSE(pbRecvBuffer, dwRecvLength); | |
for(i=0; i<dwRecvLength-2; i++) | |
printf("%c", pbRecvBuffer[i]); | |
rv = SCardDisconnect(hCard, SCARD_LEAVE_CARD); | |
CHECK("SCardDisconnect", rv); | |
rv = SCardFreeMemory(hContext, mszReaders); | |
CHECK("SCardFreeMemory", rv); | |
rv = SCardReleaseContext(hContext); | |
CHECK("SCardReleaseContext", rv); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment