/* scardcontrol.c: sample code to use/test SCardControl() API Copyright (C) 2004 Ludovic Rousseau This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * $Id$ */ #include #include #include #include #include #include #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif #define SCARD_CTL_CODE(code) (0x42000000 + (code)) #define IOCTL_SMARTCARD_VENDOR_IFD_EXCHANGE SCARD_CTL_CODE(1) #define IOCTL_SMARTCARD_VENDOR_VERIFY_PIN SCARD_CTL_CODE(2) #define IOCTL_SMARTCARD_VENDOR_MODIFY_PIN SCARD_CTL_CODE(3) #define IOCTL_SMARTCARD_VENDOR_TRANSFER_PIN SCARD_CTL_CODE(4) /* PCSC error message pretty print */ #define PCSC_ERROR_EXIT(rv, text) \ if (rv != SCARD_S_SUCCESS) \ { \ printf(text ": %s (0x%lX)\n", pcsc_stringify_error(rv), rv); \ goto end; \ } \ else \ printf(text ": OK\n\n"); #define PCSC_ERROR_CONT(rv, text) \ if (rv != SCARD_S_SUCCESS) \ printf(text ": %s (0x%lX)\n", pcsc_stringify_error(rv), rv); \ else \ printf(text ": OK\n\n"); int main(int argc, char *argv[]) { LONG rv; SCARDCONTEXT hContext; DWORD dwReaders; LPTSTR mszReaders; char *ptr, **readers = NULL; int nbReaders; SCARDHANDLE hCard; DWORD dwActiveProtocol, dwReaderLen, dwState, dwProt, dwAtrLen; BYTE pbAtr[MAX_ATR_SIZE] = ""; char pbReader[MAX_READERNAME] = ""; int reader_nb; int i, offset; unsigned char bSendBuffer[MAX_BUFFER_SIZE]; unsigned char bRecvBuffer[MAX_BUFFER_SIZE]; DWORD length; unsigned char attribute[1]; DWORD attribute_length; SCARD_IO_REQUEST pioRecvPci; printf("SCardControl sample code\n"); printf("V 1.0 2004, Ludovic Rousseau \n"); printf("\nTHIS PROGRAM IS NOT DESIGNED AS A TESTING TOOL!\n"); printf("Do NOT use it unless you really know what you do.\n\n"); rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext); if (rv != SCARD_S_SUCCESS) { printf("SCardEstablishContext: Cannot Connect to Resource Manager %lX\n", rv); return 1; } /* Retrieve the available readers list */ rv = SCardListReaders(hContext, NULL, NULL, &dwReaders); if (rv != SCARD_S_SUCCESS) { printf("SCardListReader: %lX\n", rv); } mszReaders = malloc(sizeof(char)*dwReaders); if (mszReaders == NULL) { printf("malloc: not enough memory\n"); goto end; } rv = SCardListReaders(hContext, NULL, mszReaders, &dwReaders); if (rv != SCARD_S_SUCCESS) printf("SCardListReader: %lX\n", rv); /* Extract readers from the null separated string and get the total * number of readers */ nbReaders = 0; ptr = mszReaders; while (*ptr != '\0') { ptr += strlen(ptr)+1; nbReaders++; } if (nbReaders == 0) { printf("No reader found\n"); goto end; } /* allocate the readers table */ readers = calloc(nbReaders, sizeof(char *)); if (NULL == readers) { printf("Not enough memory for readers[]\n"); goto end; } /* fill the readers table */ nbReaders = 0; ptr = mszReaders; while (*ptr != '\0') { printf("%d: %s\n", nbReaders, ptr); readers[nbReaders] = ptr; ptr += strlen(ptr)+1; nbReaders++; } if (argc > 1) { reader_nb = atoi(argv[1]); if (reader_nb < 0 || reader_nb >= nbReaders) { printf("Wrong reader index: %d\n", reader_nb); goto end; } } else reader_nb = 0; /* connect to a reader (even without a card) */ dwActiveProtocol = -1; rv = SCardConnect(hContext, readers[reader_nb], SCARD_SHARE_DIRECT, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol); printf(" Protocol: %ld\n", dwActiveProtocol); PCSC_ERROR_EXIT(rv, "SCardConnect") /* get GemPC firmware */ printf(" Get GemPC Firmware\n"); /* this is specific to Gemplus readers */ bSendBuffer[0] = 0x02; rv = SCardControl(hCard, IOCTL_SMARTCARD_VENDOR_IFD_EXCHANGE, bSendBuffer, 1, bRecvBuffer, sizeof(bRecvBuffer), &length); printf(" Firmware: "); for (i=0; i 0) { /* read the fake digits */ char in[10]; /* 4 digits + \n + \0 */ (void)fgets(in, sizeof(in), stdin); printf("keyboard sent: %s", in); } } /* card disconnect */ rv = SCardDisconnect(hCard, SCARD_UNPOWER_CARD); PCSC_ERROR_CONT(rv, "SCardDisconnect") end: /* We try to leave things as clean as possible */ rv = SCardReleaseContext(hContext); if (rv != SCARD_S_SUCCESS) printf("SCardReleaseContext: %s (0x%lX)\n", pcsc_stringify_error(rv), rv); /* free allocated memory */ free(mszReaders); free(readers); return 0; } /* main */