static int testSCardGetAttrib(SCARDCONTEXT hContext, SCARDCONTEXT hCard) { int errCount = 0; BYTE *attrib = NULL; DWORD attribLen = SCARD_AUTOALLOCATE; int ret = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING, (LPBYTE)&attrib, &attribLen); CHECK_PCSC_RET("SCardGetAttrib()", ret); if (attribLen < 8) { printf("ERR: SCardGetAttrib(): ATR length looks too small (%d) for a BE eID card\n", (int) attribLen); errCount++; } else if (attrib[0] != 0x3B) { printf("ERR: SCardGetAttrib(): ATR should start with 0x3B (instead of 0x%0x) for a BE eID card\n", attrib[0]); errCount++; } ret = SCardFreeMemory(hContext, attrib); CHECK_PCSC_RET("SCardFreeMemory()", ret); return errCount; }
int CPCSCMngr::GetAvailableReaders(char* pReaders, DWORD *pReadersLen) { int status = STAT_OK; LONG retStat = SCARD_S_SUCCESS; SCARDCONTEXT sc; DWORD len = SCARD_AUTOALLOCATE; char* readers = NULL; if ((retStat = SCardEstablishContext(SCARD_SCOPE_USER,0,0,&sc)) == SCARD_S_SUCCESS) { if ((retStat = SCardListReaders(sc, NULL, (char *)&readers, &len)) == SCARD_S_SUCCESS) { // OK, READERS OBTAINED if (*pReadersLen >= len) { memcpy(pReaders, readers, len); } else { // NOT ENOUGHT MEMORY *pReadersLen = len; status = STAT_DATA_INCORRECT_LENGTH; } SCardFreeMemory(sc, readers); } else { m_lastSCardError = retStat; status = STAT_VALUE_NOT_READ; } } SCardReleaseContext(sc); if (retStat != SCARD_S_SUCCESS) status = STAT_SCARD_ERROR; return status; }
/* ------------------------------------------------------------------------- */ char *sc_listreaders(void) { SCARDCONTEXT hCtx = {0}; LONG rc = SCARD_S_SUCCESS; DWORD dw = SCARD_AUTOALLOCATE; LPTSTR c = NULL; char *cc = NULL; rc = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hCtx); if (rc == SCARD_S_SUCCESS) { rc = SCardListReaders(hCtx, NULL, (LPTSTR) &c, &dw); if (rc == SCARD_S_SUCCESS) { cc = (char *) malloc(dw); if (cc != NULL) { cc[--dw]=0; cc[--dw]=0; while (dw--) cc[dw] = (char)((c[dw])?c[dw]:0x0A); } SCardFreeMemory(hCtx, c); } SCardReleaseContext(hCtx); } return cc; } /* sc_listreaders */
static UINT32 smartcard_ListReadersW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, ListReaders_Call* call) { UINT32 status; ListReaders_Return ret; LPWSTR mszReaders = NULL; DWORD cchReaders = 0; IRP* irp = operation->irp; cchReaders = SCARD_AUTOALLOCATE; status = ret.ReturnCode = SCardListReadersW(operation->hContext, (LPCWSTR) call->mszGroups, (LPWSTR) &mszReaders, &cchReaders); ret.msz = (BYTE*) mszReaders; ret.cBytes = cchReaders * 2; if (status != SCARD_S_SUCCESS) return status; smartcard_trace_list_readers_return(smartcard, &ret, TRUE); status = smartcard_pack_list_readers_return(smartcard, irp->output, &ret); if (status != SCARD_S_SUCCESS) return status; if (mszReaders) SCardFreeMemory(operation->hContext, mszReaders); if (call->mszGroups) free(call->mszGroups); return ret.ReturnCode; }
static DWORD smartcard_StatusW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, Status_Call* call) { LONG status; Status_Return ret; DWORD cchReaderLen = 0; LPWSTR mszReaderNames = NULL; IRP* irp = operation->irp; if (call->cbAtrLen > 32) call->cbAtrLen = 32; ret.cbAtrLen = call->cbAtrLen; ZeroMemory(ret.pbAtr, 32); cchReaderLen = SCARD_AUTOALLOCATE; status = ret.ReturnCode = SCardStatusW(operation->hCard, (LPWSTR) &mszReaderNames, &cchReaderLen, &ret.dwState, &ret.dwProtocol, (BYTE*) &ret.pbAtr, &ret.cbAtrLen); ret.mszReaderNames = (BYTE*) mszReaderNames; ret.cBytes = cchReaderLen * 2; smartcard_trace_status_return(smartcard, &ret, TRUE); status = smartcard_pack_status_return(smartcard, irp->output, &ret); if (status != SCARD_S_SUCCESS) return status; if (mszReaderNames) SCardFreeMemory(operation->hContext, mszReaderNames); return ret.ReturnCode; }
bool CPCSCClass::ListReadernames(CComboBox* m_cblist) { char *pReaderList = NULL; DWORD ReaderListSize = SCARD_AUTOALLOCATE; char *pch; if(m_cblist == NULL) { mylog.AddToLogs(m_logobj,"error: NULL combobox class"); return false; } //save the combobox to class m_cbListObj = m_cblist; m_cblist->ResetContent(); RetCode = SCardListReadersA( hContext, NULL, (LPSTR)&pReaderList, &ReaderListSize); if (RetCode != SCARD_S_SUCCESS) { mylog.AddToLogs(m_logobj,"error: SCardListReaders Failed"); mylog.AddToLogs(m_logobj,TranslatePCSCError()); return false; } else { mylog.AddToLogs(m_logobj,"SCardListReaders Success"); } pch = pReaderList; while (*pch != 0) { m_cblist->AddString (pch); pch += strlen (pch) + 1; } m_cblist->SetCurSel(0); RetCode = SCardFreeMemory( hContext, pReaderList ); if (RetCode != SCARD_S_SUCCESS) { mylog.AddToLogs(m_logobj,"error: SCardFreeMemory Failed"); } return true; }
static int testListReadersW(SCARDCONTEXT hContext) { int errCount = 0; wchar_t staticBuf[2000]; DWORD staticLen = (DWORD) (sizeof(staticBuf) / sizeof(wchar_t)); long ret = SCardListReadersW(hContext, NULL, staticBuf, &staticLen); CHECK_PCSC_RET("SCardListReadersW(1)", ret); wchar_t *dynBuf = NULL; DWORD dynLen = 0; ret = SCardListReadersW(hContext, NULL, dynBuf, &dynLen); CHECK_PCSC_RET("SCardListReadersW(2)", ret); dynBuf = (wchar_t *) malloc(dynLen * sizeof(wchar_t)); ret = SCardListReadersW(hContext, NULL, dynBuf, &dynLen); CHECK_PCSC_RET("SCardListReadersW(3)", ret); wchar_t *autoBuf = NULL; DWORD autoLen = SCARD_AUTOALLOCATE; ret = SCardListReadersW(hContext, NULL, (wchar_t*) &autoBuf, &autoLen); CHECK_PCSC_RET("SCardListReadersW(4)", ret); wchar_t *auto2Buf = NULL; DWORD auto2Len = SCARD_AUTOALLOCATE; ret = SCardListReadersW(hContext, NULL, (wchar_t*) &auto2Buf, &auto2Len); CHECK_PCSC_RET("SCardListReadersW(5)", ret); if (staticLen != dynLen || dynLen != autoLen || dynLen != auto2Len) { printf("ERR: SCardListReadersW() returned buffers lengths of different size\n"); printf(" (staticLen = %d, dynLen = %d, autoLen = %d, auto2Len = %d\n", staticLen, dynLen, autoLen, auto2Len); errCount++; } else if (memcmp(staticBuf, dynBuf, dynLen) != 0 || memcmp(dynBuf, autoBuf, dynLen) != 0 || memcmp(dynBuf, auto2Buf, dynLen) != 0) { printf("ERR: SCardListReadersW() returned different data\n"); dump(" staticBuf = '%S'\n", staticBuf, dynLen); dump(" dynBuf = '%S'\n", dynBuf, dynLen); dump(" autoBuf = '%S'\n", autoBuf, dynLen); dump(" auto2Buf = '%S'\n", auto2Buf, dynLen); errCount++; } free(dynBuf); ret = SCardFreeMemory(hContext, autoBuf); CHECK_PCSC_RET("SCardFreeMemory()", ret); return errCount; }
void SmartCardReader::listAllReaders( ) { LPTSTR pmszReaders = NULL; LPTSTR pReader; LONG lReturn, lReturn2; DWORD cch = SCARD_AUTOALLOCATE; // Retrieve the list the readers. // hSC was set by a previous call to SCardEstablishContext. lReturn = SCardListReaders( context, NULL, (LPTSTR)&pmszReaders, &cch ); if( retCode != SCARD_S_SUCCESS ) { ofLogError( "SmartCardReader::setup() FAILED TO LIST ALL READERS" ) << getSCardErrorMessage( retCode ) ; return; } else { // Do something with the multi string of readers. // Output the values. // A double-null terminates the list of values. pReader = pmszReaders; while ( '\0' != *pReader ) { // Display the value. printf("Reader: %S\n", pReader ); // Advance to the next value. pReader = pReader + wcslen((wchar_t *)pReader) + 1; } // Free the memory. lReturn2 = SCardFreeMemory( context , pmszReaders ); if ( SCARD_S_SUCCESS != lReturn2 ) printf("Failed SCardFreeMemory\n"); } if( readerName == NULL ) { ofLogError( "READER NAME IS INVALID" ) << getSCardErrorMessage( retCode ) ; return; } }
/* -------------------------------------------------------------------------- */ LONG sc_done (sc_context *ctx, DWORD lvSt) { LONG rc=SCARD_S_SUCCESS; register BYTE i=0xFF; rc=SCardDisconnect(ctx->hCard, lvSt); /* SCARD_LEAVE_CARD); */ if (rc==SCARD_S_SUCCESS) { if (ctx->rdr != NULL) SCardFreeMemory( ctx->hCtx, ctx->rdr); ctx->rdrsz=0; ctx->rdr = NULL; rc=SCardReleaseContext(ctx->hCtx); } while(i-- > 0) ctx->sw[i]=0; ctx->rw = 0; return rc; } /* sc_finish */
/* -------------------------------------------------------------------------- */ LONG sc_init (sc_context *ctx, char *rdr) { SCARD_READERSTATE rSt = {0}; LONG rc=SCARD_S_SUCCESS; LPTSTR c=NULL, cc=NULL; DWORD dw=SCARD_AUTOALLOCATE; rc=SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &ctx->hCtx); if (rc==SCARD_S_SUCCESS) { rc=SCardListReaders(ctx->hCtx, NULL, (LPTSTR) &c, &dw); if (rc==SCARD_S_SUCCESS) { cc=findfirststr(c, rdr); if (cc!=NULL) { rSt.szReader = cc; rSt.dwCurrentState = SCARD_STATE_UNAWARE; rc = SCardGetStatusChange(ctx->hCtx, 0, &rSt, 1); if ( (rSt.dwEventState & SCARD_STATE_EMPTY) > 0 ) rc = SC_BAD; else { ctx->rdr = NULL; ctx->rdrsz = SCARD_AUTOALLOCATE; ctx->CLA = 0; ctx->proto = SCARD_PCI_T0; ctx->rw = 0; rc=SCardConnect(ctx->hCtx, cc, SCARD_SHARE_SHARED, SCARD_MYPROTOSET, &ctx->hCard, &dw); if (dw==SCARD_PROTOCOL_T1) ctx->proto=SCARD_PCI_T1; else if (dw==SCARD_PROTOCOL_RAW) ctx->proto=SCARD_PCI_RAW; if (rc==SCARD_S_SUCCESS) SCardGetAttrib(ctx->hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME, (LPBYTE)&ctx->rdr, &ctx->rdrsz); } } else rc=SC_BAD; SCardFreeMemory(ctx->hCtx, c); } if ( rc != SCARD_S_SUCCESS) SCardReleaseContext(ctx->hCtx); } return rc; } /* sc_init */
static int testListReadersA(SCARDCONTEXT hContext) { int errCount = 0; char staticBuf[2000]; DWORD staticLen = (DWORD) sizeof(staticBuf); long ret = SCardListReadersA(hContext, NULL, staticBuf, &staticLen); CHECK_PCSC_RET("SCardListReadersA(1)", ret); char *dynBuf = NULL; DWORD dynLen = 0; ret = SCardListReadersA(hContext, NULL, dynBuf, &dynLen); CHECK_PCSC_RET("SCardListReadersA(2)", ret); dynBuf = (char *) malloc(dynLen); ret = SCardListReadersA(hContext, NULL, dynBuf, &dynLen); CHECK_PCSC_RET("SCardListReadersA(1)", ret); #ifndef MAC_OS_X char *autoBuf = NULL; DWORD autoLen = SCARD_AUTOALLOCATE; ret = SCardListReadersA(hContext, NULL, (char*) &autoBuf, &autoLen); CHECK_PCSC_RET("SCardListReadersA(3)", ret); if (staticLen != dynLen || dynLen != autoLen) { printf("ERR: SCardListReadersA() returned buffers lengths of different size\n"); errCount++; } else if (memcmp(staticBuf, dynBuf, dynLen) != 0 || memcmp(dynBuf, autoBuf, dynLen) != 0) { printf("ERR: SCardListReadersA() returned different data\n"); errCount++; } ret = SCardFreeMemory(hContext, autoBuf); CHECK_PCSC_RET("SCardFreeMemory()", ret); #endif free(dynBuf); return errCount; }
int main(/*@unused@*/ int argc, /*@unused@*/ char **argv) { SCARDHANDLE hCard; SCARDCONTEXT hContext; SCARD_READERSTATE_A rgReaderStates[1]; DWORD dwReaderLen, dwState, dwProt, dwAtrLen; DWORD dwPref, dwReaders = 0; char *pcReaders = NULL, *mszReaders; #ifdef USE_AUTOALLOCATE unsigned char *pbAtr = NULL; #else unsigned char pbAtr[MAX_ATR_SIZE]; #endif union { unsigned char as_char[100]; DWORD as_DWORD; uint32_t as_uint32_t; } buf; DWORD dwBufLen; unsigned char *pbAttr = NULL; DWORD pcbAttrLen; char *mszGroups; DWORD dwGroups = 0; long rv; DWORD i; int p, iReader; int iList[16]; SCARD_IO_REQUEST pioRecvPci; SCARD_IO_REQUEST pioSendPci; unsigned char bSendBuffer[MAX_BUFFER_SIZE]; unsigned char bRecvBuffer[MAX_BUFFER_SIZE]; DWORD send_length, length; (void)argc; (void)argv; printf("\nMUSCLE PC/SC Lite unitary test Program\n\n"); printf(MAGENTA "THIS PROGRAM IS NOT DESIGNED AS A TESTING TOOL FOR END USERS!\n"); printf("Do NOT use it unless you really know what you do.\n\n" NORMAL); printf("Testing SCardEstablishContext\t: "); rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext); test_rv(rv, hContext, PANIC); printf("Testing SCardIsValidContext\t: "); rv = SCardIsValidContext(hContext); test_rv(rv, hContext, PANIC); printf("Testing SCardIsValidContext\t: "); rv = SCardIsValidContext(hContext+1); test_rv(rv, hContext, DONT_PANIC); printf("Testing SCardListReaderGroups\t: "); #ifdef USE_AUTOALLOCATE dwGroups = SCARD_AUTOALLOCATE; rv = SCardListReaderGroups(hContext, (LPSTR)&mszGroups, &dwGroups); #else rv = SCardListReaderGroups(hContext, NULL, &dwGroups); test_rv(rv, hContext, PANIC); printf("Testing SCardListReaderGroups\t: "); mszGroups = calloc(dwGroups, sizeof(char)); rv = SCardListReaderGroups(hContext, mszGroups, &dwGroups); #endif test_rv(rv, hContext, PANIC); /* * Have to understand the multi-string here */ p = 0; for (i = 0; i+1 < dwGroups; i++) { ++p; printf(GREEN "Group %02d: %s\n" NORMAL, p, &mszGroups[i]); while (mszGroups[++i] != 0) ; } #ifdef USE_AUTOALLOCATE printf("Testing SCardFreeMemory\t\t: "); rv = SCardFreeMemory(hContext, mszGroups); test_rv(rv, hContext, PANIC); #else free(mszGroups); #endif wait_for_card_again: mszGroups = NULL; printf("Testing SCardListReaders\t: "); rv = SCardListReaders(hContext, mszGroups, NULL, &dwReaders); test_rv(rv, hContext, DONT_PANIC); if (SCARD_E_NO_READERS_AVAILABLE == rv) { printf("Testing SCardGetStatusChange \n"); printf("Please insert a working reader\t: "); (void)fflush(stdout); rgReaderStates[0].szReader = "\\\\?PnP?\\Notification"; rgReaderStates[0].dwCurrentState = SCARD_STATE_EMPTY; rv = SCardGetStatusChange(hContext, INFINITE, rgReaderStates, 1); test_rv(rv, hContext, PANIC); } printf("Testing SCardListReaders\t: "); #ifdef USE_AUTOALLOCATE dwReaders = SCARD_AUTOALLOCATE; rv = SCardListReaders(hContext, mszGroups, (LPSTR)&mszReaders, &dwReaders); #else rv = SCardListReaders(hContext, mszGroups, NULL, &dwReaders); test_rv(rv, hContext, PANIC); printf("Testing SCardListReaders\t: "); mszReaders = calloc(dwReaders, sizeof(char)); rv = SCardListReaders(hContext, mszGroups, mszReaders, &dwReaders); #endif test_rv(rv, hContext, DONT_PANIC); /* * Have to understand the multi-string here */ p = 0; for (i = 0; i+1 < dwReaders; i++) { ++p; printf(GREEN "Reader %02d: %s\n" NORMAL, p, &mszReaders[i]); iList[p] = i; while (mszReaders[++i] != 0) ; } if (p > 1) do { char input[80]; printf("Enter the reader number\t\t: "); (void)fgets(input, sizeof(input), stdin); (void)sscanf(input, "%d", &iReader); if (iReader > p || iReader <= 0) printf("Invalid Value - try again\n"); } while (iReader > p || iReader <= 0); else iReader = 1; rgReaderStates[0].szReader = &mszReaders[iList[iReader]]; rgReaderStates[0].dwCurrentState = SCARD_STATE_EMPTY; printf("Waiting for card insertion\t: "); (void)fflush(stdout); rv = SCardGetStatusChange(hContext, INFINITE, rgReaderStates, 1); test_rv(rv, hContext, PANIC); if (rgReaderStates[0].dwEventState & SCARD_STATE_UNKNOWN) { printf("\nA reader has been connected/disconnected\n"); goto wait_for_card_again; } printf("Testing SCardConnect\t\t: "); rv = SCardConnect(hContext, &mszReaders[iList[iReader]], SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwPref); test_rv(rv, hContext, PANIC); switch(dwPref) { case SCARD_PROTOCOL_T0: pioSendPci = *SCARD_PCI_T0; break; case SCARD_PROTOCOL_T1: pioSendPci = *SCARD_PCI_T1; break; case SCARD_PROTOCOL_RAW: pioSendPci = *SCARD_PCI_RAW; break; default: printf("Unknown protocol\n"); return -1; } int bBreak = 0; while (1) { char inputCommand[1024]; char inputAPDU[1024]; int inputAPDULen = sizeof(inputAPDU); printf("Enter APDU to send, (e.g. 00:A4:04:00:00)\n"); printf("Command APDU: "); (void)fgets(inputCommand, sizeof(inputCommand), stdin); int stringlen = strlen(inputCommand); if( inputCommand[stringlen-1] == '\n' ) { inputCommand[stringlen-1] = 0; } //remove newline int bError = sc_hex_to_bin(inputCommand, inputAPDU, &inputAPDULen); //printf("debug - value bError: %i\n",bError); if (bError) { printf("Error parsing input\n\n"); continue; } send_length = inputAPDULen; if (inputAPDULen == 0) { break; } printf("debug inputAPDULen: %i\n",inputAPDULen); memcpy(bSendBuffer, inputAPDU, send_length); length = sizeof(bRecvBuffer); printf("Testing SCardTransmit:\n "); printf("-> "); for (i=0; i<send_length; i++) { printf(" %02X", bSendBuffer[i]); } printf("\n"); rv = SCardTransmit(hCard, &pioSendPci, bSendBuffer, send_length, &pioRecvPci, bRecvBuffer, &length); test_rv(rv, hContext, PANIC); printf("<- " GREEN); for (i=0; i<length; i++) printf(" %02X", bRecvBuffer[i]); printf("\n" NORMAL); } testrun(&hCard, &hContext, &pioSendPci, 0); testrun(&hCard, &hContext, &pioSendPci, 1); testrun(&hCard, &hContext, &pioSendPci, 2); testrun(&hCard, &hContext, &pioSendPci, 3); printf("Testing SCardControl\t\t: "); #ifdef PCSC_PRE_120 { char buffer[1024] = "Foobar"; DWORD cbRecvLength = sizeof(buffer); rv = SCardControl(hCard, buffer, 7, buffer, &cbRecvLength); } #else { char buffer[1024] = { 0x02 }; DWORD cbRecvLength = sizeof(buffer); rv = SCardControl(hCard, SCARD_CTL_CODE(1), buffer, 1, buffer, sizeof(buffer), &cbRecvLength); if (cbRecvLength && (SCARD_S_SUCCESS == rv)) { for (i=0; i<cbRecvLength; i++) printf("%c", buffer[i]); printf(" "); } } #endif test_rv(rv, hContext, DONT_PANIC); printf("Testing SCardGetAttrib\t\t: "); #ifdef USE_AUTOALLOCATE pcbAttrLen = SCARD_AUTOALLOCATE; rv = SCardGetAttrib(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME, (unsigned char *)&pbAttr, &pcbAttrLen); #else rv = SCardGetAttrib(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME, NULL, &pcbAttrLen); test_rv(rv, hContext, DONT_PANIC); if (rv == SCARD_S_SUCCESS) { printf("SCARD_ATTR_DEVICE_FRIENDLY_NAME length: " GREEN "%ld\n" NORMAL, pcbAttrLen); pbAttr = malloc(pcbAttrLen); } printf("Testing SCardGetAttrib\t\t: "); rv = SCardGetAttrib(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME, pbAttr, &pcbAttrLen); #endif test_rv(rv, hContext, DONT_PANIC); if (rv == SCARD_S_SUCCESS) printf("SCARD_ATTR_DEVICE_FRIENDLY_NAME: " GREEN "%s\n" NORMAL, pbAttr); #ifdef USE_AUTOALLOCATE printf("Testing SCardFreeMemory\t\t: "); rv = SCardFreeMemory(hContext, pbAttr); test_rv(rv, hContext, PANIC); #else if (pbAttr) free(pbAttr); #endif printf("Testing SCardGetAttrib\t\t: "); #ifdef USE_AUTOALLOCATE pcbAttrLen = SCARD_AUTOALLOCATE; rv = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING, (unsigned char *)&pbAttr, &pcbAttrLen); #else rv = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING, NULL, &pcbAttrLen); test_rv(rv, hContext, DONT_PANIC); if (rv == SCARD_S_SUCCESS) { printf("SCARD_ATTR_ATR_STRING length: " GREEN "%ld\n" NORMAL, pcbAttrLen); pbAttr = malloc(pcbAttrLen); } printf("Testing SCardGetAttrib\t\t: "); rv = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING, pbAttr, &pcbAttrLen); #endif test_rv(rv, hContext, DONT_PANIC); if (rv == SCARD_S_SUCCESS) { printf("SCARD_ATTR_ATR_STRING length: " GREEN "%ld\n" NORMAL, pcbAttrLen); printf("SCARD_ATTR_ATR_STRING: " GREEN); for (i = 0; i < pcbAttrLen; i++) printf("%02X ", pbAttr[i]); printf("\n" NORMAL); } #ifdef USE_AUTOALLOCATE printf("Testing SCardFreeMemory\t\t: "); rv = SCardFreeMemory(hContext, pbAttr); test_rv(rv, hContext, PANIC); #else if (pbAttr) free(pbAttr); #endif printf("Testing SCardGetAttrib\t\t: "); dwBufLen = sizeof(buf); rv = SCardGetAttrib(hCard, SCARD_ATTR_VENDOR_IFD_VERSION, buf.as_char, &dwBufLen); test_rv(rv, hContext, DONT_PANIC); if (rv == SCARD_S_SUCCESS) printf("Vendor IFD version\t\t: " GREEN "0x%08lX\n" NORMAL, buf.as_DWORD); printf("Testing SCardGetAttrib\t\t: "); dwBufLen = sizeof(buf); rv = SCardGetAttrib(hCard, SCARD_ATTR_MAXINPUT, buf.as_char, &dwBufLen); test_rv(rv, hContext, DONT_PANIC); if (rv == SCARD_S_SUCCESS) { if (dwBufLen == sizeof(uint32_t)) printf("Max message length\t\t: " GREEN "%d\n" NORMAL, buf.as_uint32_t); else printf(RED "Wrong size" NORMAL); } printf("Testing SCardGetAttrib\t\t: "); dwBufLen = sizeof(buf); rv = SCardGetAttrib(hCard, SCARD_ATTR_VENDOR_NAME, buf.as_char, &dwBufLen); test_rv(rv, hContext, DONT_PANIC); if (rv == SCARD_S_SUCCESS) printf("Vendor name\t\t\t: " GREEN "%s\n" NORMAL, buf.as_char); printf("Testing SCardSetAttrib\t\t: "); rv = SCardSetAttrib(hCard, SCARD_ATTR_ATR_STRING, (LPCBYTE)"", 1); test_rv(rv, hContext, DONT_PANIC); printf("Testing SCardStatus\t\t: "); #ifdef USE_AUTOALLOCATE dwReaderLen = SCARD_AUTOALLOCATE; dwAtrLen = SCARD_AUTOALLOCATE; rv = SCardStatus(hCard, (LPSTR)&pcReaders, &dwReaderLen, &dwState, &dwProt, (LPBYTE)&pbAtr, &dwAtrLen); #else dwReaderLen = 100; pcReaders = malloc(sizeof(char) * 100); dwAtrLen = MAX_ATR_SIZE; rv = SCardStatus(hCard, pcReaders, &dwReaderLen, &dwState, &dwProt, pbAtr, &dwAtrLen); #endif test_rv(rv, hContext, PANIC); printf("Current Reader Name\t\t: " GREEN "%s\n" NORMAL, pcReaders); printf("Current Reader State\t\t: " GREEN "0x%.4lx\n" NORMAL, dwState); printf("Current Reader Protocol\t\t: T=" GREEN "%ld\n" NORMAL, dwProt - 1); printf("Current Reader ATR Size\t\t: " GREEN "%ld" NORMAL " bytes\n", dwAtrLen); printf("Current Reader ATR Value\t: " GREEN); for (i = 0; i < dwAtrLen; i++) { printf("%02X ", pbAtr[i]); } printf(NORMAL "\n"); #ifdef USE_AUTOALLOCATE printf("Testing SCardFreeMemory\t\t: "); rv = SCardFreeMemory(hContext, pcReaders); test_rv(rv, hContext, PANIC); printf("Testing SCardFreeMemory\t\t: "); rv = SCardFreeMemory(hContext, pbAtr); test_rv(rv, hContext, PANIC); #else if (pcReaders) free(pcReaders); #endif if (rv != SCARD_S_SUCCESS) { (void)SCardDisconnect(hCard, SCARD_RESET_CARD); (void)SCardReleaseContext(hContext); } printf("Press enter: "); (void)getchar(); printf("Testing SCardReconnect\t\t: "); rv = SCardReconnect(hCard, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, SCARD_UNPOWER_CARD, &dwPref); test_rv(rv, hContext, PANIC); printf("Testing SCardDisconnect\t\t: "); rv = SCardDisconnect(hCard, SCARD_UNPOWER_CARD); test_rv(rv, hContext, PANIC); #ifdef USE_AUTOALLOCATE printf("Testing SCardFreeMemory\t\t: "); rv = SCardFreeMemory(hContext, mszReaders); test_rv(rv, hContext, PANIC); #else free(mszReaders); #endif printf("Testing SCardReleaseContext\t: "); rv = SCardReleaseContext(hContext); test_rv(rv, hContext, PANIC); printf("\n"); printf("PC/SC Test Completed Successfully !\n"); return 0; }
int main(int argc, char *argv[]) { int Index = 0; int Arg = 1; char *VirtualCard = NULL; BCAS::Manager::Abstract *Card; argc--; while (argc > 0) { if (strcmp(argv[Arg], "-virtual") == 0) { if (argc == 1) { printf("Missing file parameter.\n"); return 1; } VirtualCard = _strdup(argv[++Arg]); argc--; } else if (strcmp(argv[Arg], "-reader") == 0) { if (argc == 1) { printf("Missing file parameter.\n"); return 1; } Index = atoi(argv[++Arg]); argc--; } else if (strcmp(argv[Arg], "-list") == 0) { Index = -1; } else { printf("Invalid parameter: %s\n", argv[Arg]); return 1; } Arg++; argc--; } if (VirtualCard == NULL) { SCARDCONTEXT Ctx; LONG Result; char *Reader = NULL; Result = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &Ctx); if (Result != SCARD_S_SUCCESS) { printf("Failed to establish context, error: %08x\n", Result); return 1; } DWORD Count = SCARD_AUTOALLOCATE; LPTSTR Readers = NULL; Result = SCardListReaders(Ctx, NULL, (LPTSTR)&Readers, &Count); if (Result != SCARD_S_SUCCESS) { if (Result == SCARD_E_NO_READERS_AVAILABLE) printf("No card readers available.\n"); else printf("Failed to list card readers, error: %08x\n", Result); SCardReleaseContext(Ctx); return 1; } LPTSTR R = Readers; Count = 0; while (*R != 0) { if (Index == Count) { Reader = _strdup(R); break; } else if (Index == -1) { printf("Reader %d: %s\n", Count, R); } R += strlen(R) + 1; Count++; } SCardFreeMemory(Ctx, Readers); if (Reader == NULL) { if (Index != -1) printf("Cannot find a reader at index %d\n", Index); SCardReleaseContext(Ctx); return 1; } BCAS::Manager::Card *RealCard = new BCAS::Manager::Card; RealCard->SetReader(Reader); Card = RealCard; } else { BCAS::Manager::Virtual *Dump = new BCAS::Manager::Virtual; Dump->SetReader(VirtualCard); Card = Dump; } BCAS::Keys::RegisterAll(); Card->Init(); BCAS::Manager::Ops *Ops = new BCAS::Manager::Ops; Ops->SetCard(Card); BCAS::Manager::Manager *Mgr = new BCAS::Manager::Manager(Ops); bool Quit = false; u16 Date; SYSTEMTIME Time; GetSystemTime(&Time); Date = ConvertDateToMJD(Time.wYear, Time.wMonth & 0xff, Time.wDay & 0xff) + 7; while (!Quit) { bool NewCard = false; bool HasCard; u16 Expiry; HasCard = Card->WaitForEvent(NewCard); if (NewCard == true) { Mgr->PrintCardInformation(CardType); if (CardType == kType_INVALID) break; PrintMenu(); continue; } if (HasCard == false) { if (_kbhit()) { int Selection = _getch(); if (Selection == 27) { break; } if (Selection == 0) _getch(); } continue; } int Key = _getch(); switch (Key) { case 27: Quit = true; break; case 0: Key = _getch(); switch (Key) { case 59: Mgr->DumpMode(); break; case 60: Mgr->PrintEntitlements(); break; case 61: Mgr->PrintEmail(); break; case 62: DateState = (DateState + 1) % 7; switch (DateState) { case 0: Expiry = 7; break; case 1: Expiry = 15; break; case 2: Expiry = 30; break; case 3: Expiry = 90; break; case 4: Expiry = 180; break; case 5: Expiry = 365 * 2; break; case 6: break; } if (DateState != 6) { GetSystemTime(&Time); Date = ConvertDateToMJD(Time.wYear, Time.wMonth & 0xff, Time.wDay & 0xff) + Expiry; } else { Date = 0xffff; } break; default: printf("%d\n", Key); break; } break; // UpdateTiers case 49: Mgr->AddEntitlement(BCAS::Keys::KEYSET_WOWOW, Date); break; case 50: Mgr->AddEntitlement(BCAS::Keys::KEYSET_STARCHANNELHD, Date); break; case 51: Mgr->AddEntitlement(BCAS::Keys::KEYSET_E2_110CS, Date); break; case 52: Mgr->AddEntitlement(BCAS::Keys::KEYSET_SAFETYNET, Date); break; case 53: Mgr->AddEntitlement(BCAS::Keys::KEYSET_NHK, Date); break; // InvalidateTiers case 113: Mgr->InvalidateEntitlement(BCAS::Keys::KEYSET_WOWOW); break; case 119: Mgr->InvalidateEntitlement(BCAS::Keys::KEYSET_STARCHANNELHD); break; case 101: Mgr->InvalidateEntitlement(BCAS::Keys::KEYSET_E2_110CS); break; case 114: Mgr->InvalidateEntitlement(BCAS::Keys::KEYSET_SAFETYNET); break; case 116: Mgr->InvalidateEntitlement(BCAS::Keys::KEYSET_NHK); break; // DeleteEmail case 97: Mgr->DeleteEmail(BCAS::Keys::KEYSET_WOWOW); break; case 115: Mgr->DeleteEmail(BCAS::Keys::KEYSET_STARCHANNELHD); break; case 100: Mgr->DeleteEmail(BCAS::Keys::KEYSET_E2_110CS); break; case 102: Mgr->DeleteEmail(BCAS::Keys::KEYSET_SAFETYNET); break; case 103: Mgr->DeleteEmail(BCAS::Keys::KEYSET_NHK); break; case 104: Mgr->DeleteEmail(BCAS::Keys::KEYSET_EMAIL); break; // ActivateTrial case 122: Mgr->ActivateTrial(BCAS::Keys::KEYSET_WOWOW, false, Date); Mgr->ActivateTrial(BCAS::Keys::KEYSET_WOWOW, true, Date); break; case 120: Mgr->ActivateTrial(BCAS::Keys::KEYSET_STARCHANNELHD, false, Date); Mgr->ActivateTrial(BCAS::Keys::KEYSET_STARCHANNELHD, true, Date); break; case 99: Mgr->ActivateTrial(BCAS::Keys::KEYSET_E2_110CS, false, Date); Mgr->ActivateTrial(BCAS::Keys::KEYSET_E2_110CS, true, Date); break; case 118: Mgr->ActivateTrial(BCAS::Keys::KEYSET_SAFETYNET, false, Date); Mgr->ActivateTrial(BCAS::Keys::KEYSET_SAFETYNET, true, Date); break; case 98: Mgr->ActivateTrial(BCAS::Keys::KEYSET_NHK, false, Date); Mgr->ActivateTrial(BCAS::Keys::KEYSET_NHK, true, Date); break; default: printf("%d\n", Key); break; } if (!Quit) PrintMenu(); } return 0; }
BOOL ProcessCardAtr(SCARDCONTEXT hContext, BYTE atr[], DWORD atrlen) { LONG lReturn = NO_ERROR; DWORD dwActiveProtocol = 0; DWORD cbAtr = MAX_ATR_LEN; DWORD dwIndex = 0; DWORD cchCards; char *pmszCards = NULL; BYTE name[MAX_PATH]; LONG rc; BOOL success = TRUE; /* Determine if the ATR is already in the Smart Card Database */ cchCards = SCARD_AUTOALLOCATE; rc = SCardListCards(hContext, atr, NULL, 0, (char *) &pmszCards, &cchCards); if (rc != SCARD_S_SUCCESS) { printf("SCardListCards error 0x%08lX (%lu).\n", rc, rc); return FALSE; } if ((pmszCards == NULL) || (*pmszCards == 0)) { /* Card not found. We need to add it. */ printf("\tThis card is currently not recognized by the system.\n"); if (!Confirm("Do you want to add this card to the 'no driver' list ?")) return TRUE; printf("\tAdding card's ATR...\n"); sprintf(name, "%s-", name_prefix); if (!ComputeCardNameFromAtr(&name[strlen(name)], atr, NULL, atrlen)) { printf("Failed to compute a name for the card.\n"); return FALSE; } success = IntroduceCardAtr(hContext, atr, NULL, atrlen, name); if (success) printf("\tOK!\n"); } else { printf("\tThis card is already known by the system.\n"); printf("\t(%s)\n", pmszCards); } // Free resources if (pmszCards != NULL) { SCardFreeMemory(hContext, pmszCards); } return success; }
int main(int argc, char **argv) { SCARDCONTEXT hContext; SCARD_READERSTATE rgscState[MAXIMUM_SMARTCARD_READERS]; DWORD dwReaders, dwReadersOld = 0; LPSTR szReaders = NULL; DWORD dwReadersSz; BOOL first_run = TRUE; DWORD i, j; LONG rc; if ((argc >= 2) && (!strcmp(argv[1], "-m"))) gbChangeMasterKey = TRUE; /* * Welcome message, check parameters * --------------------------------- */ printf("SpringCard SDK for PC/SC (CSB6 family)\n"); printf("\n"); printf("NXP DESFIRE EV0 reference demo\n"); printf("------------------------------\n"); printf("www.springcard.com\n\n"); printf("\n"); printf("Press <Ctrl+C> to exit\n\n"); /* * Get a handle to the PC/SC resource manager * ------------------------------------------ */ rc = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext); if(rc != SCARD_S_SUCCESS) { printf("SCardEstablishContext :%08lX\n",rc); return EXIT_FAILURE; } /* * Infinite loop, we'll exit only when killed by Ctrl+C * ---------------------------------------------------- */ for (;;) { /* * Get the list of available readers */ dwReadersSz = SCARD_AUTOALLOCATE; rc = SCardListReaders(hContext, NULL, /* Any group */ (LPTSTR) &szReaders, /* Diabolic cast for buffer auto-allocation */ &dwReadersSz); /* Beg for auto-allocation */ if (rc == SCARD_E_NO_READERS_AVAILABLE) { /* No reader at all */ dwReaders = 0; } else if (rc != SCARD_S_SUCCESS) { printf("SCardListReaders error %08lX\n",rc); break; } else { /* Track events on found readers. */ LPTSTR pReader = szReaders; for (dwReaders=0; dwReaders<MAXIMUM_SMARTCARD_READERS; dwReaders++) { /* End of multi-string array */ if (*pReader == '\0') break; /* Remember this reader's name */ rgscState[dwReaders].szReader = pReader; /* Jump to next entry in multi-string array */ pReader += strlen(pReader) + 1; } } if (first_run) { /* Program startup, display the number of readers */ if (dwReaders == 0) { printf("No PC/SC reader\n\n"); } else { printf("%lu PC/SC reader%s found\n\n", dwReaders, dwReaders ? "s" : ""); } } if (dwReadersOld != dwReaders) { /* Reader added, or reader removed */ /* (re)set the initial state for all readers */ for (i=0; i<dwReaders; i++) rgscState[i].dwCurrentState = SCARD_STATE_UNAWARE; if (!first_run) { int c; /* Not the program startup, explain the event */ if (dwReadersOld > dwReaders) { c = (int) dwReadersOld-dwReaders; printf("%d reader%s ha%s been removed from the system\n\n", c, (c==1)?" ":"s", (c==1)?"s":"ve"); } else { c = (int) dwReaders-dwReadersOld; printf("%d reader%s ha%s been added to the system\n\n", c, (c==1)?" ":"s", (c==1)?"s":"ve"); } } dwReadersOld = dwReaders; } if (dwReaders == 0) { /* We must wait here, because the SCardGetStatusChange doesn't wait */ /* at all in case there's no reader in the system. Silly, isn't it ? */ #ifdef WIN32 Sleep(1000); #endif #ifdef __linux__ sleep(1); #endif } /* * Interesting part of the job : call SCardGetStatusChange to monitor all changes * taking place in the PC/SC reader(s) */ rc = SCardGetStatusChange(hContext, INFINITE, rgscState, dwReaders); if (rc != SCARD_S_SUCCESS) { printf("SCardGetStatusChange error %08lX\n",rc); break; } for (i=0; i<dwReaders; i++) { BOOL just_inserted = FALSE; if (rgscState[i].dwEventState & SCARD_STATE_CHANGED) { /* Something changed since last loop */ if ( (rgscState[i].dwEventState & SCARD_STATE_PRESENT) && !(rgscState[i].dwCurrentState & SCARD_STATE_PRESENT) ) just_inserted = TRUE; /* Remember new current state for next loop */ rgscState[i].dwCurrentState = rgscState[i].dwEventState; } else { /* Nothing new, don't display anything for this reader */ /* (unless we're in the first run) */ if (!first_run) continue; } /* * Display current reader's state * ------------------------------ */ /* Reader's name */ printf("Reader %lu: %s\n", i, rgscState[i].szReader); /* Complete status */ printf("\tCard state:\n"); if (rgscState[i].dwEventState & SCARD_STATE_IGNORE) printf("\t\tIgnore this reader\n"); if (rgscState[i].dwEventState & SCARD_STATE_UNKNOWN) printf("\t\tReader unknown\n"); if (rgscState[i].dwEventState & SCARD_STATE_UNAVAILABLE) printf("\t\tStatus unavailable\n"); if (rgscState[i].dwEventState & SCARD_STATE_EMPTY) printf("\t\tNo card in the reader\n"); if (rgscState[i].dwEventState & SCARD_STATE_PRESENT) printf("\t\tCard present\n"); if (rgscState[i].dwEventState & SCARD_STATE_ATRMATCH) printf("\t\tATR match\n"); if (rgscState[i].dwEventState & SCARD_STATE_EXCLUSIVE) printf("\t\tReader reserved for exclusive use\n"); if (rgscState[i].dwEventState & SCARD_STATE_INUSE) printf("\t\tReader/card in use\n"); if (rgscState[i].dwEventState & SCARD_STATE_MUTE) printf("\t\tCard mute\n"); if (just_inserted) { /* * Display card's ATR * ------------------ */ if (rgscState[i].cbAtr) { printf("\tCard ATR:"); for (j=0; j<rgscState[i].cbAtr; j++) printf(" %02X", rgscState[i].rgbAtr[j]); printf("\n"); } /* * Do the Desfire library test on this card * ---------------------------------------- */ TestDesfire(hContext, rgscState[i].szReader); } } /* Free the list of readers */ if (szReaders != NULL) { SCardFreeMemory(hContext, szReaders); szReaders = NULL; } /* Not the first run anymore */ first_run = FALSE; } rc = SCardReleaseContext(hContext); /* Never go here (Ctrl+C kill us before !) */ return EXIT_FAILURE; }
BOOL PCSC_IccConnect (MRTD_CTX_ST * ctx, const char *pcsc_reader) { LONG rc; char *reader_name = NULL; char *reader_list = NULL; DWORD reader_list_sz; int reader_sel = -1; if (ctx == NULL) return FALSE; #ifdef WIN32 if (LoadLibrary("winscard.dll") == NULL) { MrtdSetLastError(ctx, MRTD_E_READER_NOT_AVAIL); return FALSE; } #endif /* Try to understand the pcsc_reader name */ if (pcsc_reader == NULL) { reader_sel = 0; } else if ((strlen (pcsc_reader) == 2) && (pcsc_reader[0] == '#')) { reader_sel = atoi (&pcsc_reader[1]); } /* Create the PC/SC context */ if (ctx->reader.pcsc.hcard) { SCardDisconnect (ctx->reader.pcsc.hcard, SCARD_LEAVE_CARD); ctx->reader.pcsc.hcard = 0; } if (ctx->reader.pcsc.hcontext) { SCardReleaseContext (ctx->reader.pcsc.hcontext); ctx->reader.pcsc.hcontext = 0; } rc = SCardEstablishContext (SCARD_SCOPE_USER, NULL, NULL, &ctx->reader.pcsc.hcontext); if (rc != SCARD_S_SUCCESS) { MrtdVerbose("PC/SC error %08lX", rc); MrtdSetLastError (ctx, MRTD_E_READER_NOT_FOUND); return FALSE; } /* Retrieve list of readers */ reader_list_sz = SCARD_AUTOALLOCATE; rc = SCardListReaders (ctx->reader.pcsc.hcontext, NULL, (char *) &reader_list, &reader_list_sz); if (rc != SCARD_S_SUCCESS) { MrtdVerbose("SCardListReaders : PC/SC error %08lX", rc); MrtdSetLastError (ctx, MRTD_E_READER_NOT_FOUND); return FALSE; } /* Loop inside the list */ if (reader_list != NULL) { char *p = reader_list; while (strlen (p)) { if (reader_sel < 0) { /* We must compare the names */ if (!strcmp (p, pcsc_reader)) { /* This one is OK ! */ reader_name = p; break; } } else if (reader_sel == 0) { /* We shall take this one */ reader_name = p; break; } else { /* Decrement... */ reader_sel--; } p += strlen (p) + 1; } } /* A reader has been selected ? */ if (reader_name == NULL) { SCardFreeMemory (ctx->reader.pcsc.hcontext, reader_list); MrtdSetLastError (ctx, MRTD_E_READER_NOT_FOUND); return FALSE; } MrtdVerbose("Connected to PC/SC reader \"%s\"", reader_name); /* Try to connect to the card in the reader */ rc = SCardConnect (ctx->reader.pcsc.hcontext, reader_name, SCARD_SHARE_EXCLUSIVE, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &ctx->reader.pcsc.hcard, &ctx->reader.pcsc.protocol); SCardFreeMemory (ctx->reader.pcsc.hcontext, reader_list); if (rc != SCARD_S_SUCCESS) { MrtdVerbose("SCardConnect : PC/SC error %08lX", rc); MrtdSetLastError (ctx, MRTD_E_NO_CARD); return FALSE; } if (ctx->reader.pcsc.protocol == SCARD_PROTOCOL_T0) { MrtdVerbose("Connected to a T=0 card"); } else if (ctx->reader.pcsc.protocol == SCARD_PROTOCOL_T1) { MrtdVerbose("Connected to a T=1 card"); } /* We are connected to the card */ ctx->pcsc_reader = TRUE; ctx->sprox_reader = FALSE; return TRUE; }
void PCSCResourceManager::run() { SCARDCONTEXT context; LONG rv; while (true) { rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &context); if (rv == SCARD_S_SUCCESS) { DWORD readerNum = SCARD_AUTOALLOCATE; LPSTR readerNames = NULL; do { rv = SCardListReaders(context, NULL, (LPSTR) &readerNames, &readerNum); if (rv == SCARD_S_SUCCESS) { for (LPCSTR pch = readerNames; *pch != '\0'; pch += strlen(pch) + 1) { int i; for (i = 0; i < m_availabeReaders.size(); i++) if (0 == strcmp(m_availabeReaders[i]->name(), pch)) break; if (i == m_availabeReaders.size()) { SCardReader *reader = new SCardReader(pch); m_availabeReaders.append(reader); connect(reader, SIGNAL(unavailable(LPCSTR)), SLOT(clearUnavailabeReader(LPCSTR))); reader->start(); emit readerPluged(reader); } } (void) SCardFreeMemory(context, readerNames); } else std::cout << pcsc_stringify_error(rv) << std::endl; if (rv == SCARD_S_SUCCESS || rv == SCARD_E_NO_READERS_AVAILABLE) { SCARD_READERSTATE readerStates; readerStates.szReader = "\\\\?PnP?\\Notification"; readerStates.dwCurrentState = SCARD_STATE_UNAWARE; rv = SCardGetStatusChange(context, INFINITE, &readerStates, 1); if (rv != SCARD_E_TIMEOUT || rv != SCARD_S_SUCCESS) { (void) SCardReleaseContext(context); break; } } else { (void) SCardReleaseContext(context); break; } } while (true); } else { std::cout << pcsc_stringify_error(rv) << std::endl; QThread::sleep(PCSC_ERROR_BREAK_TIME); } } }
printf("response: "); for(i=0; i<dwRecvLength; i++){ printf("%02X ", pbRecvBuffer[i]); } printf("\n"); } } } } } // printf("j:%d",j); } rv = SCardDisconnect(hCard, SCARD_LEAVE_CARD); CHECK("SCardDisconnect", rv) #ifdef SCARD_AUTOALLOCATE rv = SCardFreeMemory(hContext, mszReaders); CHECK("SCardFreeMemory", rv) #else free(mszReaders); #endif rv = SCardReleaseContext(hContext); CHECK("SCardReleaseContext", rv) return 0; }
BOOL MonitorReaders(SCARDCONTEXT hContext) { DWORD dwReaders, dwReadersOld = 0; SCARD_READERSTATE *rgscState; LPSTR szReaders = NULL; DWORD dwReadersSz; DWORD maxReaders; BOOL bFirstRun = TRUE; DWORD i, j; LONG rc; /* Constant MAXIMUM_SMARTCARD_READERS is only 10 in Windows SDK */ /* This is not enough for most of our tests. 64 sounds good... */ maxReaders = MAXIMUM_SMARTCARD_READERS; if (maxReaders<64) maxReaders = 64; rgscState = calloc(maxReaders, sizeof(SCARD_READERSTATE)); if (rgscState == NULL) { printf("Out of memory\n"); return FALSE; } for (;;) { /* Get the list of available readers */ dwReadersSz = SCARD_AUTOALLOCATE; rc = SCardListReaders(hContext, NULL, /* Any group */ (LPTSTR) &szReaders, /* Diabolic cast for buffer auto-allocation */ &dwReadersSz); /* Beg for auto-allocation */ if (rc == SCARD_E_NO_READERS_AVAILABLE) { /* No reader at all */ dwReaders = 0; } else if (rc != SCARD_S_SUCCESS) { printf("SCardListReaders error 0x%08lX (%lu).\n", rc, rc); break; } else { /* Track events on found readers. */ LPTSTR pReader = szReaders; for (dwReaders=0; dwReaders<maxReaders; dwReaders++) { /* End of multi-string array */ if (*pReader == '\0') break; /* Remember this reader's name */ rgscState[dwReaders].szReader = pReader; /* Jump to next entry in multi-string array */ pReader += strlen(pReader) + 1; } } if (bFirstRun) { /* Program startup, display the number of readers */ if (dwReaders == 0) { printf("No PC/SC reader\n\n"); } else { printf("%ld PC/SC reader%s found\n\n", dwReaders, dwReaders ? "s" : ""); } } if (dwReadersOld != dwReaders) { /* Reader added, or reader removed */ /* (re)set the initial state for all readers */ for (i=0; i<dwReaders; i++) rgscState[i].dwCurrentState = SCARD_STATE_UNAWARE; if (!bFirstRun) { int c; /* Not the program startup, explain the event */ if (dwReadersOld > dwReaders) { c = (int) dwReadersOld-dwReaders; printf("%d reader%s ha%s been removed from the system\n\n", c, (c==1)?" ":"s", (c==1)?"s":"ve"); } else { c = (int) dwReaders-dwReadersOld; printf("%d reader%s ha%s been added to the system\n\n", c, (c==1)?" ":"s", (c==1)?"s":"ve"); } } dwReadersOld = dwReaders; } if (dwReaders == 0) { /* We must wait here, because the SCardGetStatusChange doesn't wait */ /* at all in case there's no reader in the system. Silly, isn't it ? */ Sleep(1000); } /* * Interesting part of the job : call SCardGetStatusChange to monitor all changes * taking place in the PC/SC reader(s) */ rc = SCardGetStatusChange(hContext, INFINITE, rgscState, dwReaders); if (rc != SCARD_S_SUCCESS) { printf("SCardGetStatusChange error 0x%08lX (%lu).\n", rc, rc); if (rc == SCARD_F_INTERNAL_ERROR) { /* Oups ? Restard from scratch after 2500ms */ if (szReaders != NULL) { SCardFreeMemory(hContext, szReaders); szReaders = NULL; } Sleep(2500); continue; } break; } for (i=0; i<dwReaders; i++) { BOOL just_inserted = FALSE; if (rgscState[i].dwEventState & SCARD_STATE_CHANGED) { /* Something changed since last loop */ if ( (rgscState[i].dwEventState & SCARD_STATE_PRESENT) && !(rgscState[i].dwCurrentState & SCARD_STATE_PRESENT) ) just_inserted = TRUE; /* Remember new current state for next loop */ rgscState[i].dwCurrentState = rgscState[i].dwEventState; } else { /* Nothing new, don't display anything for this reader */ /* (unless we're in the first run) */ if (!bFirstRun) continue; } if (just_inserted) { printf("Card inserted in %s\n", rgscState[i].szReader); if (rgscState[i].dwEventState & SCARD_STATE_MUTE) { printf("\tCard is mute\n"); } else { printf("\tATR: "); for (j=0; j<rgscState[i].cbAtr; j++) printf("%02X", rgscState[i].rgbAtr[j]); printf("\n"); if (!ProcessCardAtr(hContext, rgscState[i].rgbAtr, rgscState[i].cbAtr)) return FALSE; printf("\n"); } } } /* Free the list of readers */ if (szReaders != NULL) { SCardFreeMemory(hContext, szReaders); szReaders = NULL; } /* Not the first run anymore */ bFirstRun = FALSE; } /* Never go here (Ctrl+C kill us before !) */ free(rgscState); return TRUE; }
void listReaders() { LPTSTR pmszReaders = NULL; LPTSTR pReader; LONG lReturn, lReturn2; DWORD cch = SCARD_AUTOALLOCATE; int i = 0; SCardEstablishContext( SCARD_SCOPE_USER, // Scope of the resource manager context. NULL, // r.f.u NULL, // r.f.u &m_hContext); // Returns the resource manager handle. // Retrieve the list the readers. // hSC was set by a previous call to SCardEstablishContext. lReturn = SCardListReaders(m_hContext, NULL, (LPTSTR)&pmszReaders, &cch); switch(lReturn) { case SCARD_E_NO_READERS_AVAILABLE: printf("Reader is not in groups.\n"); // Take appropriate action. // ... break; case SCARD_S_SUCCESS: // Do something with the multi string of readers. // Output the values. // A double-null terminates the list of values. pReader = pmszReaders; while ('\0' != *pReader) { // Display the value. printf("Reader: %S\n", pReader); // Advance to the next value. pReader = pReader + wcslen((wchar_t*)pReader) + 1; ++i; } printf("number of readers = %d\n", i); // Free the memory. lReturn2 = SCardFreeMemory(m_hContext, pmszReaders); if (SCARD_S_SUCCESS != lReturn2) printf("Failed SCardFreeMemory\n"); break; default: printf("Failed SCardListReaders 0x%X\n", lReturn); //break; if (lReturn == SCARD_E_SERVICE_STOPPED) { printf("service stopped\n"); } // Take appropriate action. // ... break; } SCardReleaseContext(m_hContext); //SCardEstablishContext( // SCARD_SCOPE_USER, // Scope of the resource manager context. // NULL, // r.f.u // NULL, // r.f.u // &m_hContext); // Returns the resource manager handle. }
PCSC::PCSC( std::string& a_stInputReaderName, u2& a_u2PortNumber, std::string& a_stURI, u4& a_NameSpaceHivecode, u2& a_TypeHivecode, u4& a_Index ) { Log::begin( "PCSC::PCSC" ); m_bDoTransact = true; std::string stIdentifiedReaderName = ""; LPTSTR pReaderList = NULL; if( a_stInputReaderName.empty( ) ) { a_stInputReaderName = "selfdiscover"; } m_hContextPCSC = 0; m_hCardPCSC = 0; LONG lReturn = SCardEstablishContext( 0, NULL, NULL, &m_hContextPCSC ); if( SCARD_S_SUCCESS != lReturn ) { std::string msg = ""; Log::toString( msg, "SCardEstablishContext <%#02x>", lReturn ); Log::error( "PCSC::PCSC", msg.c_str( ) ); throw RemotingException((lpCharPtr)"PCSC: SCardEstablishContext error",lReturn); } // self-discovery mechanism #ifdef WIN32 if (_stricmp("selfdiscover", a_stInputReaderName.c_str()) == 0) { #else if (strncasecmp("selfdiscover", a_stInputReaderName.c_str(),a_stInputReaderName.length()) == 0) { #endif // In Windows SCARD_AUTOALLOCATE (-1) as a value of readerListChatLength // would signal the SCardListReaders to determine the size of reader string // This is not available in Linux so we call the SCardListReaders twice. First // to get the length and then the reader names. #ifdef WIN32 DWORD readerListCharLength = SCARD_AUTOALLOCATE; lReturn = SCardListReaders( m_hContextPCSC, NULL, (LPTSTR)&pReaderList, &readerListCharLength); #else DWORD readerListCharLength = 0; lReturn = SCardListReaders(m_hContextPCSC,NULL,NULL,&readerListCharLength); if(lReturn != SCARD_S_SUCCESS) throw RemotingException((lpCharPtr)"PCSC: SCardListReaders error",lReturn); pReaderList = (lpCharPtr)malloc(sizeof(char)*readerListCharLength); lReturn = SCardListReaders(m_hContextPCSC, NULL,pReaderList, &readerListCharLength); #endif if(lReturn != SCARD_S_SUCCESS) { std::string msg = ""; Log::toString( msg, "SCardListReaders <%#02x>", lReturn ); Log::error( "PCSC::PCSC", msg.c_str( ) ); throw RemotingException((lpCharPtr)"PCSC: SCardListReaders error",lReturn); } else { u4 count = 0; u1 foundReader = FALSE; SCARDHANDLE finalCardHandle = 0; try { lpTCharPtr pReader = pReaderList; while ('\0' != *pReader ) { size_t readerNameLen = strlen((const char*)pReader); SCARD_READERSTATE readerStates[1]; readerStates[0].dwCurrentState = SCARD_STATE_UNAWARE; readerStates[0].szReader = pReader; if ( SCardGetStatusChange( m_hContextPCSC, 0, readerStates, 1) == SCARD_S_SUCCESS) { if ((readerStates[0].dwEventState & SCARD_STATE_PRESENT) == SCARD_STATE_PRESENT) { // we found a card in this reader stIdentifiedReaderName = pReader; DWORD activeProtocol; lReturn = SCardConnect( m_hContextPCSC, (LPTSTR)stIdentifiedReaderName.c_str(), SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &m_hCardPCSC, &activeProtocol); if (lReturn == SCARD_S_SUCCESS) { // try to identify if we're dealing with a .NetCard u1 answerData[258]; DWORD answerLen = 258; Log::log( "PCSC::PCSC SCardTransmit..." ); lReturn = SCardTransmit( m_hCardPCSC, SCARD_PCI_T0, isNetCardAPDU, sizeof(isNetCardAPDU), NULL, (LPBYTE)answerData, &answerLen); Log::log( "PCSC::PCSC - SCardTransmit <%#02x>", lReturn ); if (lReturn == SCARD_S_SUCCESS) { u1 rethrowException = FALSE; try { if (answerData[answerLen - 2] == 0x61) { if (answerData[answerLen - 1] > 10) { u1Array invokeAPDU(0); invokeAPDU += (u1)0xD8; invokeAPDU += (u2)CARDMANAGER_SERVICE_PORT; invokeAPDU += (u1)0x6F; invokeAPDU += (u4)HIVECODE_NAMESPACE_SMARTCARD; invokeAPDU += (u2)HIVECODE_TYPE_SMARTCARD_CONTENTMANAGER; invokeAPDU += (u2)HIVECODE_METHOD_SMARTCARD_CONTENTMANAGER_GETASSOCIATEDPORT; std::string* cmServicem_stURI = new std::string(CARDMANAGER_SERVICE_NAME); invokeAPDU.Append(cmServicem_stURI); delete cmServicem_stURI; invokeAPDU += (u4)a_NameSpaceHivecode; invokeAPDU += (u2)a_TypeHivecode; invokeAPDU.Append(&a_stURI); // construct call if(invokeAPDU.GetLength() <= (s4)APDU_TO_CARD_MAX_SIZE) { u1Array apdu(5); apdu.GetBuffer()[0] = 0x80; apdu.GetBuffer()[1] = 0xC2; apdu.GetBuffer()[2] = 0x00; apdu.GetBuffer()[3] = 0x00; apdu.GetBuffer()[4] = (u1)invokeAPDU.GetLength(); apdu += invokeAPDU; u1Array answer(0); Log::log( "PCSC::PCSC - ExchangeData..." ); exchangeData(apdu, answer); Log::log( "PCSC::PCSC - ExchangeData ok" ); Log::log( "PCSC::PCSC - CheckForException..." ); u4 protocolOffset = m_MarshallerUtil.CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_INT32); Log::log( "PCSC::PCSC - CheckForException ok" ); u4 discoveredPortNumber = m_MarshallerUtil.ComReadU4At(answer, protocolOffset); if ((a_u2PortNumber == 0) || (discoveredPortNumber == a_u2PortNumber)) { a_u2PortNumber = (u2)discoveredPortNumber; if (foundReader == TRUE) { if (a_Index == 0) { // this is the second reader/card/app that matches - we error at this point rethrowException = TRUE; std::string errorMessage( "At least 2 cards posses \""); errorMessage += a_stURI.c_str( ); errorMessage += "\" service\r\nRemove conflicting cards from your system"; Log::error( "PCSC::PCSC", errorMessage.c_str( ) ); throw RemotingException(errorMessage); } } foundReader = TRUE; finalCardHandle = m_hCardPCSC; // Advance to the next value. count++; if (count == a_Index) { // we enumerate one by one the valid readers - so stop here break; } pReader = (lpTCharPtr)((lpTCharPtr)pReader + readerNameLen + 1); continue; } } } } } catch (...) { if (rethrowException == TRUE) { throw; } else { // swallow exception } } SCardDisconnect( m_hCardPCSC, SCARD_LEAVE_CARD); m_hCardPCSC = 0; } // this is not a .NetCard, or the service was not found - let's try another reader/card else { Log::error( "PCSC::PCSC", "SCardTransmit failed" ); } } else { Log::error( "PCSC::PCSC", "SCardConnect failed" ); } } else { Log::error( "PCSC::PCSC", "SCARD_STATE_PRESENT not present" ); } } else { Log::error( "PCSC::PCSC", "SCardGetStatusChange != SCARD_S_SUCCESS" ); } // Advance to the next value. pReader = (lpTCharPtr)((lpTCharPtr)pReader + readerNameLen + 1); } } catch (...) { stIdentifiedReaderName = ""; #ifdef WIN32 /*lReturn = */SCardFreeMemory( m_hContextPCSC, pReaderList); /*if(lReturn != SCARD_S_SUCCESS) { throw RemotingException((lpCharPtr)"PCSC: SCardFreeMemory error",lReturn); }*/ #else if( pReaderList ) { free(pReaderList); } #endif throw; } // have we found anything ? if( !foundReader) { stIdentifiedReaderName = ""; #ifdef WIN32 /*lReturn = */SCardFreeMemory( m_hContextPCSC, pReaderList); //if(lReturn != SCARD_S_SUCCESS) { // throw RemotingException((lpCharPtr)"PCSC: SCardFreeMemory error",lReturn); //} #else if(pReaderList ) { free(pReaderList); } #endif throw RemotingException((lpCharPtr)"Could not find any .NET smart card", SCARD_E_NO_SMARTCARD ); } m_hCardPCSC = finalCardHandle; } m_stReaderName = stIdentifiedReaderName; } else { m_stReaderName = a_stInputReaderName; } Log::end( "PCSC::PCSC" ); } /* */ void PCSC::exchangeData( u1Array &dataIn, u1Array &dataout ) { // check validity of handle if ( SCARD_S_SUCCESS != SCardIsValidContext( m_hContextPCSC ) ) { throw RemotingException( (lpCharPtr)"PCSC: Invalid handle", SCARD_E_INVALID_HANDLE ); } try { if( m_bDoTransact ) { beginTransaction( ); } unsigned char ucRetry = 0; do { ucRetry++; unsigned char answerData[ 258 ]; memset( answerData, 0, sizeof( answerData ) ); DWORD answerLen = sizeof( answerData ); #ifdef __DEBUG_APDU__ Log::logCK_UTF8CHAR_PTR( "PCSC::ExchangeData - Command", dataIn.GetBuffer( ), dataIn.GetLength( ) ); Timer t; t.start( ); #endif LONG lReturn = SCardTransmit( m_hCardPCSC, SCARD_PCI_T0, dataIn.GetBuffer( ), dataIn.GetLength( ), NULL, (lpByte)answerData, &answerLen ); if( SCARD_S_SUCCESS != lReturn ) { std::string msg = ""; Log::toString( msg, "SCardTransmit <%#02x>", lReturn ); Log::error( "PCSC::ExchangeData", msg.c_str( ) ); } if( ( SCARD_W_REMOVED_CARD == lReturn ) || ( SCARD_W_RESET_CARD == lReturn ) ) { DWORD dwActiveProtocol = SCARD_PROTOCOL_T0; lReturn = SCardReconnect( m_hCardPCSC, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, SCARD_LEAVE_CARD, &dwActiveProtocol ); if( SCARD_S_SUCCESS != lReturn ) { std::string msg = ""; Log::toString( msg, "SCardReconnect <%#02x>", lReturn ); Log::error( "PCSC::ExchangeData", msg.c_str( ) ); throw RemotingException( (lpCharPtr)"PCSC: SCardReconnect error", lReturn ); } lReturn = SCardTransmit( m_hCardPCSC, SCARD_PCI_T0, dataIn.GetBuffer( ), dataIn.GetLength( ), NULL, (lpByte)answerData, &answerLen ); if( SCARD_S_SUCCESS != lReturn ) { Log::log( "PCSC::ExchangeData - SCardTransmit <%#02x>", lReturn ); } } else if( SCARD_S_SUCCESS != lReturn ) { std::string s; Log::toString( s, "SCardTransmit failed <%#02x>", lReturn ); Log::error( "PCSC::ExchangeData", s.c_str( ) ); throw RemotingException( (lpCharPtr)"PCSC: SCardTransmit error", lReturn ); } if (answerLen < 2) { Log::error( "PCSC::ExchangeData", "Incorrect length returned" ); throw RemotingException((lpCharPtr)"PCSC: SCardTransmit error - Incorrect length returned",SCARD_F_COMM_ERROR); } if (answerLen > 2) { u1Array temp(answerLen - 2); temp.SetBuffer(answerData); dataout += temp; } u1 sw1 = answerData[answerLen - 2]; u1 sw2 = answerData[answerLen - 1]; #ifdef __DEBUG_APDU__ Log::log( "PCSC::ExchangeData - Status (1) <%02x%02x>", sw1, sw2 ); Log::logCK_UTF8CHAR_PTR( "PCSC::ExchangeData - Response", answerData, answerLen ); t.stop( "PCSC::ExchangeData - Response" ); #endif while( (sw1 == 0x61 ) || ( sw1 == 0x9F ) ) { memset( answerData, 0, sizeof( answerData ) ); unsigned char GetResponse[ 5 ]; memset( GetResponse, 0, sizeof( GetResponse ) ); if (sw1 == 0x9F) { GetResponse[0] = 0xA0; } else { GetResponse[0] = 0x00; } GetResponse[1] = 0xC0; GetResponse[2] = 0x00; GetResponse[3] = 0x00; GetResponse[4] = sw2; answerLen = 258; #ifdef __DEBUG_APDU__ Log::logCK_UTF8CHAR_PTR( "PCSC::ExchangeData - Command", GetResponse, sizeof( GetResponse ) ); t.start( ); #endif lReturn = SCardTransmit( m_hCardPCSC, SCARD_PCI_T0, (lpCByte)GetResponse, 5, NULL, (lpByte)answerData, &answerLen ); if( ( SCARD_W_REMOVED_CARD == lReturn ) || ( SCARD_W_RESET_CARD == lReturn ) ) { DWORD dwActiveProtocol = SCARD_PROTOCOL_T0; lReturn = SCardReconnect( m_hCardPCSC, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, SCARD_LEAVE_CARD, &dwActiveProtocol ); lReturn = SCardTransmit( m_hCardPCSC, SCARD_PCI_T0, (lpCByte)GetResponse, 5, NULL, (lpByte)answerData, &answerLen ); } else if( SCARD_S_SUCCESS != lReturn ) { std::string s; Log::toString( s, "SCardTransmit failed <%02x>", lReturn ); Log::error( "PCSC::ExchangeData", s.c_str( ) ); throw RemotingException( (lpCharPtr)"PCSC: SCardTransmit error", lReturn ); } if( answerLen < 2 ) { Log::error( "PCSC::ExchangeData", "Incorrect length returned" ); throw RemotingException( (lpCharPtr)"PCSC: SCardTransmit error - Incorrect length returned", SCARD_F_COMM_ERROR ); } if( answerLen > 2 ) { u1Array temp( answerLen - 2 ); temp.SetBuffer( answerData ); dataout += temp; } sw1 = answerData[ answerLen - 2 ]; sw2 = answerData[ answerLen - 1 ]; #ifdef __DEBUG_APDU__ Log::log( "PCSC::ExchangeData - Status (2) <%02x%02x>", sw1, sw2 ); Log::logCK_UTF8CHAR_PTR( "PCSC::ExchangeData - Response", answerData, answerLen ); t.stop( "PCSC::ExchangeData - Response" ); #endif } // The response is not acceptable. We have to retry the data transmission if( ( 0x63 == sw1 ) || ( ( 0x69 == sw1 ) && ( 0x99 == sw2 ) ) ) { Log::log( "PCSC::ExchangeData - Invalid response. Retry" ); } else { break; } /* if( ( 0x90 == sw1 ) && ( 0x00 == sw2 ) ) { break; }*/ } while ( 3 > ucRetry ); } catch (...) { if( m_bDoTransact ) { endTransaction( ); } throw; } if( m_bDoTransact ) { endTransaction( ); } } /* Cleanup the context and card handle */ PCSC::~PCSC( ) { if( m_hCardPCSC ) { SCardDisconnect( m_hCardPCSC, SCARD_LEAVE_CARD ); m_hCardPCSC = 0; } if( m_hContextPCSC ) { SCardReleaseContext( m_hContextPCSC ); m_hContextPCSC = 0; } } MARSHALLER_NS_END
int main(/*@unused@*/ int argc, /*@unused@*/ char **argv) { SCARDHANDLE hCard; SCARDCONTEXT hContext; SCARD_READERSTATE rgReaderStates[1]; DWORD dwReaderLen, dwState, dwProt, dwAtrLen; DWORD dwPref, dwReaders = 0; char *pcReader = NULL, *mszReaders; #ifdef USE_AUTOALLOCATE unsigned char *pbAtr = NULL; #else unsigned char pbAtr[MAX_ATR_SIZE]; #endif union { unsigned char as_char[100]; DWORD as_DWORD; uint32_t as_uint32_t; } buf; DWORD dwBufLen; unsigned char *pbAttr = NULL; DWORD pcbAttrLen; char *mszGroups; DWORD dwGroups = 0; long rv; DWORD i; int p, iReader; int iList[16] = {0}; SCARD_IO_REQUEST ioRecvPci = *SCARD_PCI_T0; /* use a default value */ const SCARD_IO_REQUEST *pioSendPci; unsigned char bSendBuffer[MAX_BUFFER_SIZE]; unsigned char bRecvBuffer[MAX_BUFFER_SIZE]; DWORD send_length, length; (void)argc; (void)argv; printf("\nMUSCLE PC/SC Lite unitary test Program\n\n"); printf(MAGENTA "THIS PROGRAM IS NOT DESIGNED AS A TESTING TOOL FOR END USERS!\n"); printf("Do NOT use it unless you really know what you do.\n\n" NORMAL); printf("Testing SCardEstablishContext\t: "); rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext); test_rv(rv, hContext, PANIC); printf("Testing SCardIsValidContext\t: "); rv = SCardIsValidContext(hContext); test_rv(rv, hContext, PANIC); printf("Testing SCardIsValidContext\t: "); rv = SCardIsValidContext(hContext+1); test_rv(rv, hContext, DONT_PANIC); printf("Testing SCardListReaderGroups\t: "); #ifdef USE_AUTOALLOCATE dwGroups = SCARD_AUTOALLOCATE; rv = SCardListReaderGroups(hContext, (LPSTR)&mszGroups, &dwGroups); #else rv = SCardListReaderGroups(hContext, NULL, &dwGroups); test_rv(rv, hContext, PANIC); printf("Testing SCardListReaderGroups\t: "); mszGroups = calloc(dwGroups, sizeof(char)); rv = SCardListReaderGroups(hContext, mszGroups, &dwGroups); #endif test_rv(rv, hContext, PANIC); /* * Have to understand the multi-string here */ p = 0; for (i = 0; i+1 < dwGroups; i++) { ++p; printf(GREEN "Group %02d: %s\n" NORMAL, p, &mszGroups[i]); while (mszGroups[++i] != 0) ; } #ifdef USE_AUTOALLOCATE printf("Testing SCardFreeMemory\t\t: "); rv = SCardFreeMemory(hContext, mszGroups); test_rv(rv, hContext, PANIC); #else free(mszGroups); #endif wait_for_card_again: mszGroups = NULL; printf("Testing SCardListReaders\t: "); rv = SCardListReaders(hContext, mszGroups, NULL, &dwReaders); test_rv(rv, hContext, DONT_PANIC); if (SCARD_E_NO_READERS_AVAILABLE == rv) { printf("Testing SCardGetStatusChange \n"); printf("Please insert a working reader\t: "); (void)fflush(stdout); rgReaderStates[0].szReader = "\\\\?PnP?\\Notification"; rgReaderStates[0].dwCurrentState = SCARD_STATE_EMPTY; rv = SCardGetStatusChange(hContext, INFINITE, rgReaderStates, 1); test_rv(rv, hContext, PANIC); } printf("Testing SCardListReaders\t: "); #ifdef USE_AUTOALLOCATE dwReaders = SCARD_AUTOALLOCATE; rv = SCardListReaders(hContext, mszGroups, (LPSTR)&mszReaders, &dwReaders); #else rv = SCardListReaders(hContext, mszGroups, NULL, &dwReaders); test_rv(rv, hContext, PANIC); printf("Testing SCardListReaders\t: "); mszReaders = calloc(dwReaders, sizeof(char)); rv = SCardListReaders(hContext, mszGroups, mszReaders, &dwReaders); #endif test_rv(rv, hContext, DONT_PANIC); /* * Have to understand the multi-string here */ p = 0; for (i = 0; i+1 < dwReaders; i++) { ++p; printf(GREEN "Reader %02d: %s\n" NORMAL, p, &mszReaders[i]); iList[p] = i; while (mszReaders[++i] != 0) ; } if (p > 1) do { char input[80]; char *r; printf("Enter the reader number\t\t: "); r = fgets(input, sizeof(input), stdin); if (NULL == r) iReader = -1; else iReader = atoi(input); if (iReader > p || iReader <= 0) printf("Invalid Value - try again\n"); } while (iReader > p || iReader <= 0); else iReader = 1; rgReaderStates[0].szReader = &mszReaders[iList[iReader]]; rgReaderStates[0].dwCurrentState = SCARD_STATE_EMPTY; printf("Waiting for card insertion\t: "); (void)fflush(stdout); rv = SCardGetStatusChange(hContext, INFINITE, rgReaderStates, 1); test_rv(rv, hContext, PANIC); if (rgReaderStates[0].dwEventState & SCARD_STATE_UNKNOWN) { printf("\nA reader has been connected/disconnected\n"); goto wait_for_card_again; } printf("Testing SCardConnect\t\t: "); rv = SCardConnect(hContext, &mszReaders[iList[iReader]], SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwPref); test_rv(rv, hContext, PANIC); switch(dwPref) { case SCARD_PROTOCOL_T0: pioSendPci = SCARD_PCI_T0; break; case SCARD_PROTOCOL_T1: pioSendPci = SCARD_PCI_T1; break; case SCARD_PROTOCOL_RAW: pioSendPci = SCARD_PCI_RAW; break; default: printf("Unknown protocol\n"); return -1; } /* APDU select file */ printf("Select file:"); send_length = 7; memcpy(bSendBuffer, "\x00\xA4\x00\x00\x02\x3F\x00", send_length); for (i=0; i<send_length; i++) printf(" %02X", bSendBuffer[i]); printf("\n"); length = sizeof(bRecvBuffer); printf("Testing SCardTransmit\t\t: "); rv = SCardTransmit(hCard, pioSendPci, bSendBuffer, send_length, &ioRecvPci, bRecvBuffer, &length); test_rv(rv, hContext, PANIC); printf(" card response:" GREEN); for (i=0; i<length; i++) printf(" %02X", bRecvBuffer[i]); printf("\n" NORMAL); printf("Testing SCardControl\t\t: "); #ifdef PCSC_PRE_120 { char buffer[1024] = "Foobar"; DWORD cbRecvLength = sizeof(buffer); rv = SCardControl(hCard, buffer, 7, buffer, &cbRecvLength); } #else { char buffer[1024] = { 0x02 }; DWORD cbRecvLength = sizeof(buffer); rv = SCardControl(hCard, SCARD_CTL_CODE(1), buffer, 1, buffer, sizeof(buffer), &cbRecvLength); if (cbRecvLength && (SCARD_S_SUCCESS == rv)) { for (i=0; i<cbRecvLength; i++) printf("%c", buffer[i]); printf(" "); } } #endif test_rv(rv, hContext, DONT_PANIC); printf("Testing SCardGetAttrib\t\t: "); #ifdef USE_AUTOALLOCATE pcbAttrLen = SCARD_AUTOALLOCATE; rv = SCardGetAttrib(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME, (unsigned char *)&pbAttr, &pcbAttrLen); #else rv = SCardGetAttrib(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME, NULL, &pcbAttrLen); test_rv(rv, hContext, DONT_PANIC); if (rv == SCARD_S_SUCCESS) { printf("SCARD_ATTR_DEVICE_FRIENDLY_NAME length: " GREEN "%ld\n" NORMAL, pcbAttrLen); pbAttr = malloc(pcbAttrLen); } printf("Testing SCardGetAttrib\t\t: "); rv = SCardGetAttrib(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME, pbAttr, &pcbAttrLen); #endif test_rv(rv, hContext, DONT_PANIC); if (rv == SCARD_S_SUCCESS) printf("SCARD_ATTR_DEVICE_FRIENDLY_NAME: " GREEN "%s\n" NORMAL, pbAttr); #ifdef USE_AUTOALLOCATE printf("Testing SCardFreeMemory\t\t: "); rv = SCardFreeMemory(hContext, pbAttr); test_rv(rv, hContext, PANIC); #else if (pbAttr) free(pbAttr); #endif printf("Testing SCardGetAttrib\t\t: "); #ifdef USE_AUTOALLOCATE pcbAttrLen = SCARD_AUTOALLOCATE; rv = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING, (unsigned char *)&pbAttr, &pcbAttrLen); #else rv = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING, NULL, &pcbAttrLen); test_rv(rv, hContext, DONT_PANIC); if (rv == SCARD_S_SUCCESS) { printf("SCARD_ATTR_ATR_STRING length: " GREEN "%ld\n" NORMAL, pcbAttrLen); pbAttr = malloc(pcbAttrLen); } printf("Testing SCardGetAttrib\t\t: "); rv = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING, pbAttr, &pcbAttrLen); #endif test_rv(rv, hContext, DONT_PANIC); if (rv == SCARD_S_SUCCESS) { printf("SCARD_ATTR_ATR_STRING length: " GREEN "%ld\n" NORMAL, pcbAttrLen); printf("SCARD_ATTR_ATR_STRING: " GREEN); for (i = 0; i < pcbAttrLen; i++) printf("%02X ", pbAttr[i]); printf("\n" NORMAL); } #ifdef USE_AUTOALLOCATE printf("Testing SCardFreeMemory\t\t: "); rv = SCardFreeMemory(hContext, pbAttr); test_rv(rv, hContext, PANIC); #else if (pbAttr) free(pbAttr); #endif printf("Testing SCardGetAttrib\t\t: "); dwBufLen = sizeof(buf); rv = SCardGetAttrib(hCard, SCARD_ATTR_VENDOR_IFD_VERSION, buf.as_char, &dwBufLen); test_rv(rv, hContext, DONT_PANIC); if (rv == SCARD_S_SUCCESS) { int valid = 1; /* valid value by default */ long value; printf("Vendor IFD version\t\t: "); if (dwBufLen == sizeof(DWORD)) value = buf.as_DWORD; else { if (dwBufLen == sizeof(uint32_t)) value = buf.as_uint32_t; else { printf(RED "Unsupported size\n" NORMAL); valid = 0; /* invalid value */ } } if (valid) { int M = (value & 0xFF000000) >> 24; /* Major */ int m = (value & 0x00FF0000) >> 16; /* Minor */ int b = (value & 0x0000FFFF); /* build */ printf(GREEN "%d.%d.%d\n" NORMAL, M, m, b); } }
static uint32 handle_ListReaders(IRP* irp, tbool wide) { uint32 len, rv; SCARDCONTEXT hContext; DWORD dwReaders; char *readerList = NULL, *walker; int elemLength, dataLength; int pos, poslen1, poslen2; stream_seek(irp->input, 8); stream_read_uint32(irp->input, len); stream_seek(irp->input, 0x1c); stream_read_uint32(irp->input, len); if (len != 4) return SCARD_F_INTERNAL_ERROR; stream_read_uint32(irp->input, hContext); /* ignore rest of [MS-RDPESC] 2.2.2.4 ListReaders_Call */ rv = SCARD_S_SUCCESS; #ifdef SCARD_AUTOALLOCATE dwReaders = SCARD_AUTOALLOCATE; rv = SCardListReaders(hContext, NULL, (LPSTR) &readerList, &dwReaders); #else rv = SCardListReaders(hContext, NULL, NULL, &dwReaders); readerList = xmalloc(dwReaders); rv = SCardListReaders(hContext, NULL, readerList, &dwReaders); #endif if (rv != SCARD_S_SUCCESS) { DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(rv), (unsigned) rv); return rv; } /* DEBUG_SCARD("Success 0x%08x %d %d", (unsigned) hContext, (unsigned) cchReaders, (int) strlen(readerList));*/ poslen1 = stream_get_pos(irp->output); stream_seek_uint32(irp->output); stream_write_uint32(irp->output, 0x01760650); poslen2 = stream_get_pos(irp->output); stream_seek_uint32(irp->output); walker = readerList; dataLength = 0; while (1) { elemLength = strlen(walker); if (elemLength == 0) break; dataLength += sc_output_string(irp, walker, wide); walker += elemLength + 1; elemLength = strlen(walker); } dataLength += sc_output_string(irp, "\0", wide); pos = stream_get_pos(irp->output); stream_set_pos(irp->output, poslen1); stream_write_uint32(irp->output, dataLength); stream_set_pos(irp->output, poslen2); stream_write_uint32(irp->output, dataLength); stream_set_pos(irp->output, pos); sc_output_repos(irp, dataLength); sc_output_alignment(irp, 8); #ifdef SCARD_AUTOALLOCATE SCardFreeMemory(hContext, readerList); #else xfree(readerList); #endif return rv; }
int _tmain(int argc, _TCHAR* argv[]) { //WCHAR* pmszReaders = NULL; WCHAR* pBmszReaders; WCHAR* pfirstReader; WCHAR* pnexttReader; LONG retval = 0; SCARDCONTEXT hContext; DWORD cchReaders = SCARD_AUTOALLOCATE; DWORD dwTotalLen = 0; SCARDHANDLE hCard; DWORD dwActiveProtocol; // BYTE SW1, SW2; LPBYTE pbAttr = NULL; DWORD cByte = SCARD_AUTOALLOCATE; // DWORD i; DWORD iSleep = 250; retval = SCardEstablishContext ( SCARD_SCOPE_USER,NULL,NULL,&hContext); if(retval == SCARD_S_SUCCESS) { retval = SCardListReaders(hContext,NULL,(LPWSTR)&pBmszReaders,&cchReaders); if(retval == SCARD_S_SUCCESS) { pfirstReader = pBmszReaders; pnexttReader = pfirstReader; while(cchReaders > dwTotalLen+1) { //testGetATR_3(&hContext, pnexttReader); /* do { retval = SCardConnect(hContext,pnexttReader, SCARD_SHARE_EXCLUSIVE,SCARD_PROTOCOL_T0,&hCard,&dwActiveProtocol); } while (retval != SCARD_S_SUCCESS); wprintf(L"YAY, exclusive access, sleeping now for 10 minutes\n"); Sleep(600000); SCardReleaseContext(hContext); wprintf(L"YAY, released access, waiting for keystroke\n"); getchar();*/ retval = SCardConnect(hContext,pnexttReader, SCARD_SHARE_SHARED,SCARD_PROTOCOL_T0,&hCard,&dwActiveProtocol); if(retval == SCARD_S_SUCCESS) { //BeidSelectCACApplets1(hCard); //SendMSCmd(hCard); //BeidSelectCACApplets2(hCard); BeidSelectBELPICApplets(hCard); GetCardData(hCard); //testMinidriverStartSequence(&hCard); //testMacNewcardIssue(&hCard); //testCardConfusedIssue(&hCard); //testIDAIDSelect(&hCard); //testBELPICAIDSelect(&hCard); //testGetATR(&hCard); //testGetATR_2(&hCard); //testFullPathSelect(&hCard); //testStatus(&hCard); //testPPDU_GetFeatureList(&hCard); SCardDisconnect(hCard,SCARD_RESET_CARD); } else { wprintf(L"SCardConnect to %s failed\n",pfirstReader); } dwTotalLen += wcslen(pnexttReader)+1; if(dwTotalLen < cchReaders) pnexttReader = pfirstReader + dwTotalLen; } /*SCARD_LEAVE_CARD Do not do anything special. SCARD_RESET_CARD Reset the card. SCARD_UNPOWER_CARD Power down the card. SCARD_EJECT_CARD Eject the card.*/ SCardFreeMemory(hContext, pBmszReaders); } else { printf("SCardListReaders failed\n"); } } else { printf("SCardEstablishContext failed\n"); } SCardReleaseContext(hContext); printf("retval = %d\n",retval); getchar(); return 0; }