|
|
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <afx.h>
#include <afxtempl.h>
#include <winioctl.h>
#include <winsmcrd.h>
#include "ifdtest.h"
class CCardProvider *CCardProvider::s_pFirst;
#define INSERT_CARD "Please insert smart card"
#define REMOVE_CARD "Please remove smart card"
PCHAR CAtr::GetAtrString( PCHAR in_pchBuffer ) { for (ULONG i = 0; i < m_uAtrLength; i++) {
sprintf(in_pchBuffer + i * 3, "%02X ", m_rgbAtr[i]); }
return in_pchBuffer; }
CCardProvider::CCardProvider( void ) { m_pNext = NULL; m_uTestNo = 0; m_bCardTested = FALSE; m_bTestFailed = FALSE; m_pSetProtocol = NULL; m_pCardTest = NULL; }
CCardProvider::CCardProvider( void (*in_pEntryFunction)(class CCardProvider&) ) /*++
Routine Description: Constructor for class CCardProvider. This constructor is called for every card that is to be tested. It creates a new instance and appends it to a singly linked list
Arguments:
Pointer to function that registers all test functions
--*/ { class CCardProvider *l_pCardProvider;
*this = CCardProvider();
if (s_pFirst == NULL) {
s_pFirst = new CCardProvider; l_pCardProvider = s_pFirst;
} else {
l_pCardProvider = s_pFirst;
while (l_pCardProvider->m_pNext) {
l_pCardProvider = l_pCardProvider->m_pNext; }
l_pCardProvider->m_pNext = new CCardProvider; l_pCardProvider = l_pCardProvider->m_pNext; }
(*in_pEntryFunction)(*l_pCardProvider); }
BOOL CCardProvider::CardsUntested( void ) { class CCardProvider *l_pCCardProvider = s_pFirst;
while (l_pCCardProvider) {
if (l_pCCardProvider->m_bCardTested == FALSE) {
return TRUE; }
l_pCCardProvider = l_pCCardProvider->m_pNext; }
return FALSE; }
void CCardProvider::CardTest( class CReader& io_pCReader, ULONG in_uTestNo ) /*++
Routine Description:
Calls every registered card provider in the list until one of the providers indicates that it recognized the card
Arguments:
io_pCReader - reference to the test structure
Return Value:
IFDSTATUS value
--*/ { class CCardProvider *l_pCCardProvider = s_pFirst; ULONG l_uStatus;
while (l_pCCardProvider) {
if ( l_pCCardProvider->IsValidAtr(io_pCReader.GetAtr()) ) {
if (l_pCCardProvider->m_bCardTested) {
// We tested this card already
LogMessage("Card has been tested already. Please remove the card"); return; }
l_pCCardProvider->m_bCardTested = TRUE; LogMessage( "\nTesting card %s", (LPCSTR) l_pCCardProvider->m_CCardName );
if (l_pCCardProvider->m_pSetProtocol == NULL) {
return; }
// Call card provider function
l_uStatus = (*l_pCCardProvider->m_pSetProtocol)( *l_pCCardProvider, io_pCReader );
if (l_uStatus == IFDSTATUS_END) {
return; }
if (l_uStatus != IFDSTATUS_SUCCESS) {
return; }
// Check if the card test function pointer exists
if (l_pCCardProvider->m_pCardTest == NULL) {
return; }
if (in_uTestNo) {
// user wants to run only a single test
l_pCCardProvider->m_uTestNo = in_uTestNo;
LogMessage("Test No. %2d", l_pCCardProvider->m_uTestNo);
// Call card provider function
l_uStatus = (*l_pCCardProvider->m_pCardTest)( *l_pCCardProvider, io_pCReader );
return; }
// run the whole test set
for (l_pCCardProvider->m_uTestNo = 1; ;l_pCCardProvider->m_uTestNo++) {
LogMessage("Test No. %2d", l_pCCardProvider->m_uTestNo);
// Call card provider function
l_uStatus = (*l_pCCardProvider->m_pCardTest)( *l_pCCardProvider, io_pCReader );
if (l_uStatus != IFDSTATUS_SUCCESS) {
return; } } } l_pCCardProvider = l_pCCardProvider->m_pNext; }
PCHAR l_rgbAtrBuffer = new CHAR[256];
LogMessage("Card unknown!"); LogMessage(" CURRENT CARD"); LogMessage(" %s", io_pCReader.GetAtrString(l_rgbAtrBuffer));
for (l_pCCardProvider = s_pFirst; l_pCCardProvider; l_pCCardProvider = l_pCCardProvider->m_pNext) {
if (l_pCCardProvider->m_bCardTested == FALSE) {
LogMessage(" * %s", (LPCSTR) l_pCCardProvider->m_CCardName); for (int i = 0; i < MAX_NUM_ATR && l_pCCardProvider->m_CAtr[i].GetLength(); i++) { LogMessage(" %s", l_pCCardProvider->m_CAtr[i].GetAtrString(l_rgbAtrBuffer)); } } }
delete l_rgbAtrBuffer;
LogMessage("Please remove card"); }
void CCardProvider::ListUntestedCards( void ) /*++
Routine Description: Prints a list of all cards that have not been tested
--*/ { class CCardProvider *l_pCCardProvider = s_pFirst;
while (l_pCCardProvider) {
if (l_pCCardProvider->m_bCardTested == FALSE) {
LogMessage(" * %s", (LPCSTR) l_pCCardProvider->m_CCardName); }
l_pCCardProvider = l_pCCardProvider->m_pNext; } }
void CCardProvider::SetAtr( BYTE in_rgbAtr[], ULONG in_uAtrLength ) /*++
Routine Description: Sets the ATR of the card
Arguments: in_rgchAtr - the atr string in_uAtrLength - length of the atr
--*/ { for (int i = 0; i < MAX_NUM_ATR; i++) {
if (m_CAtr[i].GetLength() == 0) {
m_CAtr[i] = CAtr(in_rgbAtr, in_uAtrLength); return; } } }
void CCardProvider::SetCardName( CHAR in_rgchCardName[] ) /*++
Routine Description: Sets a friendly name for the card
Arguments: in_rgchCardName - Friendly name for the card
--*/ { m_CCardName = in_rgchCardName; }
void CheckCardMonitor( CReader &in_CReader ) { ULONG l_lResult, l_uReplyLength, l_lTestNo = 1; time_t l_lStartTime; BOOL l_bResult; OVERLAPPED l_Ovr; HANDLE l_hReader = in_CReader.GetHandle();
l_Ovr.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); ResetEvent(l_Ovr.hEvent);
LogMessage("============================="); LogMessage("Part A: Checking card monitor"); LogMessage("=============================");
LogMessage(" << %s", REMOVE_CARD); in_CReader.WaitForCardRemoval(); TestStart("%2d. %s", l_lTestNo++, INSERT_CARD); l_lResult = in_CReader.WaitForCardInsertion(); TEST_CHECK_SUCCESS("Reader failed card insertion monitor", l_lResult); TestEnd();
TestStart("%2d. IOCTL_SMARTCARD_IS_PRESENT", l_lTestNo++); l_bResult = DeviceIoControl ( l_hReader, IOCTL_SMARTCARD_IS_PRESENT, NULL, 0, NULL, 0, &l_uReplyLength, &l_Ovr );
TestCheck( l_bResult == TRUE, "DeviceIoControl should return TRUE with card inserted" ); TestEnd();
TestStart("%2d. %s", l_lTestNo++, REMOVE_CARD); l_lResult = in_CReader.WaitForCardRemoval(); TEST_CHECK_SUCCESS("Reader failed card removal monitor", l_lResult); TestEnd();
TestStart("%2d. IOCTL_SMARTCARD_IS_ABSENT", l_lTestNo++); l_bResult = DeviceIoControl ( l_hReader, IOCTL_SMARTCARD_IS_ABSENT, NULL, 0, NULL, 0, &l_uReplyLength, &l_Ovr );
TestCheck( l_bResult == TRUE, "DeviceIoControl should return TRUE with card removed" ); TestEnd();
TestStart("%2d. Insert and remove a smart card repeatedly", l_lTestNo++);
for (l_lStartTime = time(NULL); time(NULL) - l_lStartTime < 15;) {
l_lResult = in_CReader.ColdResetCard(); #ifdef insert_remove_alternate
l_bResult = DeviceIoControl ( l_hReader, IOCTL_SMARTCARD_IS_PRESENT, NULL, 0, NULL, 0, &l_uReplyLength, &l_Ovr );
SetLastError(0);
l_bResult = GetOverlappedResult( l_hReader, &l_Ovr, &l_uReplyLength, FALSE );
l_lResult = GetLastError();
TestCheck( l_bResult == TRUE && l_lResult == ERROR_SUCCESS || l_bResult == FALSE && (l_lResult == ERROR_IO_INCOMPLETE || l_lResult == ERROR_BUSY || l_lResult == ERROR_IO_PENDING), "Reader failed card insertion monitor.\nReturned %2lxH", l_lResult );
l_bResult = DeviceIoControl ( l_hReader, IOCTL_SMARTCARD_IS_ABSENT, NULL, 0, NULL, 0, &l_uReplyLength, &l_Ovr );
SetLastError(0);
l_bResult = GetOverlappedResult( l_hReader, &l_Ovr, &l_uReplyLength, FALSE );
l_lResult = GetLastError();
TestCheck( l_bResult == TRUE && l_lResult == ERROR_SUCCESS || l_bResult == FALSE && (l_lResult == ERROR_IO_INCOMPLETE || l_lResult == ERROR_BUSY || l_lResult == ERROR_IO_PENDING), "Reader failed card removal monitor:\nReturned %2lxH", l_lResult ); #endif
} #ifdef insert_remove_alternate
l_bResult = GetOverlappedResult( l_hReader, &l_Ovr, &l_uReplyLength, TRUE ); #endif
TestEnd();
LogMessage("Press any key to continue"); _getch();
if (ReaderFailed()) {
exit(-1); } }
void CheckReader( CReader &in_CReader ) /*++
Routine Description:
Checks the attributes of a reader. Once with card inserted and then without
Arguments:
Return Value:
--*/ { BOOL l_bResult; ULONG l_iIndex, l_uReplyLength, l_lTestNo = 1, l_uStart, l_uEnd; OVERLAPPED l_Ovr; UCHAR l_rgbReplyBuffer[512]; HANDLE l_hReader = in_CReader.GetHandle();
l_Ovr.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); ResetEvent(l_Ovr.hEvent);
#define ATTR(x) #x, x
struct {
PCHAR m_pchName; ULONG m_uType;
} l_aAttr[] = {
ATTR(SCARD_ATTR_VENDOR_NAME), ATTR(SCARD_ATTR_VENDOR_IFD_TYPE), ATTR(SCARD_ATTR_DEVICE_UNIT), ATTR(SCARD_ATTR_ATR_STRING), ATTR(SCARD_ATTR_DEFAULT_CLK), ATTR(SCARD_ATTR_MAX_CLK), ATTR(SCARD_ATTR_DEFAULT_DATA_RATE), ATTR(SCARD_ATTR_MAX_DATA_RATE), ATTR(SCARD_ATTR_MAX_IFSD), ATTR(SCARD_ATTR_CURRENT_PROTOCOL_TYPE), ATTR(SCARD_ATTR_PROTOCOL_TYPES), 0, 0, ATTR(SCARD_ATTR_ATR_STRING), ATTR(SCARD_ATTR_CURRENT_PROTOCOL_TYPE) };
LogMessage("======================="); LogMessage("Part B: Checking reader"); LogMessage("=======================");
BOOL l_bCardInserted = FALSE; LogMessage(" << %s", REMOVE_CARD); in_CReader.WaitForCardRemoval();
TestStart("%2d. Device name", l_lTestNo++);
CString l_COperatingSystem = GetOperatingSystem();
if (l_COperatingSystem == OS_WINNT4) {
TestCheck( in_CReader.GetDeviceName().Left(12) == "\\\\.\\SCReader", "Device name is not NT 4.0 compliant" );
} else if (l_COperatingSystem == OS_WIN95 || l_COperatingSystem == OS_WIN98) {
// there is no special naming convention for Win9x
} else {
TestCheck( in_CReader.GetDeviceName().Find("{50dd5230-ba8a-11d1-bf5d-0000f805f530}") != -1, "Device name is not WDM PnP compliant" ); } TestEnd();
TestStart( "%2d. Null pointer check", l_lTestNo++ );
for (l_iIndex = 0; l_aAttr[l_iIndex].m_pchName; l_iIndex++) {
// try to crash reader by using null pointers as arguments
l_bResult = DeviceIoControl ( l_hReader, IOCTL_SMARTCARD_GET_ATTRIBUTE, &l_aAttr[l_iIndex].m_uType, sizeof(ULONG), NULL, 1000, &l_uReplyLength, &l_Ovr );
ULONG l_lResult = GetLastError();
TestCheck( l_lResult == ERROR_INSUFFICIENT_BUFFER || l_lResult == ERROR_BAD_COMMAND, "IOCTL_SMARTCARD_GET_ATTRIBUTE (%lxh) should fail\nReturned %2lxH (NTSTATUS %lxH)\nExpected %2lxH (NTSTATUS %lxH)\nor %2lxH (NTSTATUS %lxH)", l_aAttr[l_iIndex].m_uType & 0xFFFF, l_lResult, MapWinErrorToNtStatus(l_lResult), ERROR_INSUFFICIENT_BUFFER, MapWinErrorToNtStatus(ERROR_BAD_COMMAND), ERROR_BAD_COMMAND, MapWinErrorToNtStatus(ERROR_BAD_COMMAND) ); } TestEnd();
for (l_iIndex = 0; l_iIndex < sizeof(l_aAttr) / sizeof(l_aAttr[0]); l_iIndex++) {
if (l_aAttr[l_iIndex].m_pchName == 0) {
TestStart("%2d. Close driver with I/O-request still pending", l_lTestNo++);
// Check if the reader correctly terminates pending io-requests
l_bResult = DeviceIoControl ( l_hReader, IOCTL_SMARTCARD_IS_PRESENT, NULL, 0, NULL, 0, &l_uReplyLength, &l_Ovr );
TestCheck( l_bResult == FALSE, "Wait for present succeeded with no card inserted" );
// With the pending i/o request close and re-open the driver
in_CReader.Close(); l_bResult = in_CReader.Open();
TestCheck( l_bResult, "Reader failed to terminate pending i/o request" );
TestEnd();
if (TestFailed()) {
// If the open failed we can't contiue
exit(GetLastError()); }
l_hReader = in_CReader.GetHandle();
LogMessage(" >> Please insert 'IBM PC/SC Compliance Test Card'"); in_CReader.WaitForCardInsertion(); l_bCardInserted = TRUE;
// Cold reset
TestStart("%2d. Cold reset", l_lTestNo++); l_uStart = clock(); LONG l_lResult = in_CReader.ColdResetCard(); l_uEnd = clock(); TEST_CHECK_SUCCESS("Cold reset failed", l_lResult); TestCheck( (l_uEnd - l_uStart) / CLOCKS_PER_SEC <= 2, "Cold reset took too long.\nElapsed time %ld sec\nExpected time %ld sec", (l_uEnd - l_uStart) / CLOCKS_PER_SEC, 2 ); TestEnd();
if (TestFailed()) {
exit(l_lResult); }
// Set protocol
TestStart("%2d. Set protocol to T0 | T1", l_lTestNo++); l_lResult = in_CReader.SetProtocol( SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1 ); TEST_CHECK_SUCCESS("Set protocol failed", l_lResult); TestEnd(); continue; }
TestStart("%2d. %s", l_lTestNo++, l_aAttr[l_iIndex].m_pchName);
SetLastError(0); *(PULONG) l_rgbReplyBuffer = 0;
l_bResult = DeviceIoControl ( l_hReader, IOCTL_SMARTCARD_GET_ATTRIBUTE, &l_aAttr[l_iIndex].m_uType, sizeof(ULONG), l_rgbReplyBuffer, sizeof(l_rgbReplyBuffer), &l_uReplyLength, &l_Ovr );
if (l_bResult == FALSE && GetLastError() == ERROR_IO_PENDING) {
//
// The I/O request returned pending, so
// wait until the request is finished
//
SetLastError(0);
l_bResult = GetOverlappedResult( l_hReader, &l_Ovr, &l_uReplyLength, TRUE ); }
if (GetLastError() != ERROR_SUCCESS) {
l_bResult = FALSE;
} else {
l_rgbReplyBuffer[l_uReplyLength] = 0; }
LONG l_lResult = GetLastError();
switch (l_aAttr[l_iIndex].m_uType) {
case SCARD_ATTR_VENDOR_NAME: TEST_CHECK_SUCCESS( "Ioctl SCARD_ATTR_VENDOR_NAME failed", l_lResult ); TestCheck( strlen((PCHAR) l_rgbReplyBuffer) != 0, "No vendor name defined" ); TestEnd(); break;
case SCARD_ATTR_VENDOR_IFD_TYPE: TEST_CHECK_SUCCESS( "Ioctl SCARD_ATTR_VENDOR_IFD_TYPE failed", l_lResult ); TestCheck( strlen((PCHAR) l_rgbReplyBuffer) != 0, "No ifd type defined" ); TestEnd(); break;
case SCARD_ATTR_DEVICE_UNIT: TEST_CHECK_SUCCESS( "Ioctl SCARD_ATTR_DEVICE_UNIT failed", l_lResult ); TestCheck( *(PULONG) l_rgbReplyBuffer < 4, "Invalid value: %ld (0 - 3)", *(PULONG) l_rgbReplyBuffer ); TestEnd(); break;
case SCARD_ATTR_ATR_STRING: if (l_bCardInserted) {
TEST_CHECK_SUCCESS( "Ioctl SCARD_ATTR_ATR_STRING failed", l_lResult );
} else {
TestCheck( l_bResult == FALSE, "Reader returned ATR with no card inserted" ); } TestEnd(); break;
case SCARD_ATTR_DEFAULT_CLK: case SCARD_ATTR_MAX_CLK: TEST_CHECK_SUCCESS( "Ioctl SCARD_ATTR_DEFAULT_CLK/SCARD_ATTR_MAX_CLK failed", l_lResult ); TestCheck( *(PULONG) l_rgbReplyBuffer >= 1000 && *(PULONG) l_rgbReplyBuffer <= 20000, "Invalid value %ld (1000 - 20000)", *(PULONG) l_rgbReplyBuffer ); TestEnd(); break;
case SCARD_ATTR_DEFAULT_DATA_RATE: case SCARD_ATTR_MAX_DATA_RATE: TEST_CHECK_SUCCESS( "Ioctl SCARD_ATTR_DEFAULT_DATA_RATE/SCARD_ATTR_MAX_DATA_RATE failed", l_lResult ); TestEnd(); break;
case SCARD_ATTR_MAX_IFSD: TEST_CHECK_SUCCESS( "Ioctl SCARD_ATTR_MAX_IFSD failed", l_lResult ); TestCheck( *(PULONG) l_rgbReplyBuffer >= 1 && *(PULONG) l_rgbReplyBuffer <= 254, "Invalid value: %ld (1 - 254)", *(PULONG) l_rgbReplyBuffer ); TestEnd(); break;
case SCARD_ATTR_PROTOCOL_TYPES: TEST_CHECK_SUCCESS( "Ioctl SCARD_ATTR_PROTOCOL_TYPES failed", l_lResult );
// check if the reader at least supports T=0 and T=1
TestCheck( (*(PULONG) l_rgbReplyBuffer & SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1) == (SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1), "Reader must support T=0 and T=1" ); TestEnd(); break;
case SCARD_ATTR_CURRENT_PROTOCOL_TYPE:
if (l_bCardInserted) {
TEST_CHECK_SUCCESS( "Ioctl SCARD_ATTR_CURRENT_PROTOCOL_TYPE failed", l_lResult );
TestCheck( *(PULONG) l_rgbReplyBuffer != 0, "Reader returned no protocol" );
} else {
// Check that without a card the current protocol is set to 0
TestCheck( l_bResult == FALSE, "Ioctl SCARD_ATTR_CURRENT_PROTOCOL_TYPE failed should fail with no card inserted" ); } TestEnd(); break;
default: TestCheck( l_bResult, "Ioctl returned %lxh", GetLastError() ); TestEnd(); break; } }
LogMessage(" << %s", REMOVE_CARD); in_CReader.WaitForCardRemoval(); LogMessage(" << Please insert smart card BACKWARDS"); in_CReader.WaitForCardInsertion();
TestStart("%2d. IOCTL_SMARTCARD_GET_STATE", l_lTestNo++); ULONG l_uState;
l_bResult = DeviceIoControl ( l_hReader, IOCTL_SMARTCARD_GET_STATE, NULL, 0, &l_uState, sizeof(l_uState), &l_uReplyLength, &l_Ovr );
LONG l_lResult = GetLastError();
TestCheck( l_bResult, "IOCTL_SMARTCARD_GET_STATE failed.\nReturned %8lxH (NTSTATUS %8lxH).\nExpected %8lxH (NTSTATUS %8lxH)", l_lResult, MapWinErrorToNtStatus(l_lResult), ERROR_SUCCESS, MapWinErrorToNtStatus(ERROR_SUCCESS) );
TestCheck( l_uState <= SCARD_SWALLOWED, "Invalid reader state.\nReturned %d\nExpected <= %d", l_uState, SCARD_SWALLOWED );
TestEnd();
TestStart("%2d. Cold reset", l_lTestNo++); l_uStart = clock(); l_lResult = in_CReader.ColdResetCard(); l_uEnd = clock();
TestCheck( l_lResult == ERROR_UNRECOGNIZED_MEDIA, "Cold reset failed.\nReturned %8lxH (NTSTATUS %8lxH).\nExpected %8lxH (NTSTATUS %8lxH)", l_lResult, MapWinErrorToNtStatus(l_lResult), ERROR_UNRECOGNIZED_MEDIA, MapWinErrorToNtStatus(ERROR_UNRECOGNIZED_MEDIA) );
TestCheck( (l_uEnd - l_uStart) / CLOCKS_PER_SEC <= 2, "Cold reset took too long.\nElapsed time %ld sec\nExpected time %ld sec", (l_uEnd - l_uStart) / CLOCKS_PER_SEC, 2 );
TestEnd(); }
void SimulateResMngr( CReader &in_CReader ) { BOOL l_bWaitForPresent = FALSE, l_bWaitForAbsent = FALSE, l_bResult; BOOL l_bMustWait = FALSE, l_bPoweredDown = FALSE; ULONG l_uState, l_uStatus, l_uReplyLength, l_uStateExpected = SCARD_ABSENT, l_lTestNo = 1; ULONG l_uMinorIoctl; OVERLAPPED l_Ovr, l_OvrWait; HANDLE l_hReader = in_CReader.GetHandle();
l_Ovr.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); ResetEvent(l_Ovr.hEvent);
l_OvrWait.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); ResetEvent(l_OvrWait.hEvent);
LogMessage("==================================="); LogMessage("Part C: Resource Manager Simulation"); LogMessage("===================================");
LogMessage(" << %s", REMOVE_CARD); in_CReader.WaitForCardRemoval();
while (TRUE) {
TestStart("%2d. IOCTL_SMARTCARD_GET_STATE", l_lTestNo++);
l_bResult = DeviceIoControl ( l_hReader, IOCTL_SMARTCARD_GET_STATE, NULL, 0, &l_uState, sizeof(l_uState), &l_uReplyLength, &l_Ovr );
LONG l_lResult = GetLastError();
TestCheck( l_bResult, "IOCTL_SMARTCARD_GET_STATE failed.\nReturned %8lxH (NTSTATUS %8lxH).\nExpected %8lxH (NTSTATUS %8lxH)", l_lResult, MapWinErrorToNtStatus(l_lResult), ERROR_SUCCESS, MapWinErrorToNtStatus(ERROR_SUCCESS) );
TestEnd();
if (l_bWaitForPresent) {
TestStart("%2d. %s", l_lTestNo++, INSERT_CARD);
l_bResult = GetOverlappedResult( l_hReader, &l_OvrWait, &l_uReplyLength, TRUE );
l_lResult = GetLastError();
TestCheck( l_bResult, "Card insertion monitor failed.\nReturned %8lxH (NTSTATUS %8lxH).\nExpected %8lxH (NTSTATUS %8lxH)", l_lResult, MapWinErrorToNtStatus(l_lResult), ERROR_SUCCESS, MapWinErrorToNtStatus(ERROR_SUCCESS) ); l_lResult = GetLastError();
TestEnd();
l_bWaitForPresent = FALSE; continue; }
if (l_bWaitForAbsent) {
if (l_bMustWait) {
TestStart("%2d. %s", l_lTestNo++, REMOVE_CARD);
} else {
TestStart("%2d. GetOverlappedResult", l_lTestNo++); }
l_bResult = GetOverlappedResult( l_hReader, &l_OvrWait, &l_uReplyLength, l_bMustWait );
if (l_bMustWait == FALSE) {
TestCheck( l_bResult == FALSE, "Smart card not removed" );
TestEnd();
if (TestFailed()) {
return; }
} else {
l_lResult = GetLastError();
TestCheck( l_bResult, "Card removal monitor failed.\nReturned %8lxH (NTSTATUS %8lxH).\nExpected %8lxH (NTSTATUS %8lxH)", l_lResult, MapWinErrorToNtStatus(l_lResult), ERROR_SUCCESS, MapWinErrorToNtStatus(ERROR_SUCCESS) );
TestEnd();
if (TestFailed()) {
return; } l_bWaitForAbsent = FALSE; continue; } }
TestStart("%2d. Checking reader status", l_lTestNo++);
switch (l_uState) {
case SCARD_UNKNOWN: TestCheck(FALSE, "Reader returned illegal state SCARD_UNKNOWN"); TestEnd(); return;
case SCARD_ABSENT: TestCheck( l_uStateExpected == SCARD_ABSENT, "Invalid reader state.\nCurrent state = %d\nExpected state = %d", l_uState, l_uStateExpected );
TestEnd();
if (TestFailed()) {
return; }
if (l_bMustWait) {
return; }
TestStart("%2d. IOCTL_SMARTCARD_IS_PRESENT", l_lTestNo++);
l_bResult = DeviceIoControl ( l_hReader, IOCTL_SMARTCARD_IS_PRESENT, NULL, 0, NULL, 0, &l_uReplyLength, &l_OvrWait );
TestCheck( GetLastError() == ERROR_IO_PENDING, "Monitor is supposed to return ERROR_IO_PENDING (%lxh)", GetLastError() );
TestEnd();
if (TestFailed()) {
return; }
l_bWaitForPresent = TRUE; l_uStateExpected = SCARD_PRESENT; break;
case SCARD_PRESENT: case SCARD_SWALLOWED: case SCARD_POWERED: if (l_bPoweredDown) {
TestCheck( l_uStateExpected <= SCARD_POWERED, "Invalid reader state.\nCurrent state = %d\nExpected state <= %d", l_uState, l_uStateExpected );
TestEnd();
if (TestFailed()) {
return; }
l_bMustWait = TRUE; l_uStateExpected = SCARD_ABSENT; break; }
TestCheck( l_uStateExpected > SCARD_ABSENT, "Invalid reader state.\nCurrent state = %d\nExpected state <= %d", l_uState, l_uStateExpected );
TestEnd();
if (TestFailed()) {
return; }
TestStart("%2d. IOCTL_SMARTCARD_IS_ABSENT", l_lTestNo++); l_bResult = DeviceIoControl ( l_hReader, IOCTL_SMARTCARD_IS_ABSENT, NULL, 0, NULL, 0, &l_uReplyLength, &l_OvrWait );
l_lResult = GetLastError();
TestCheck( l_bResult == FALSE, "IOCTL_SMARTCARD_IS_ABSENT should fail.\nReturned %8lxH (NTSTATUS %8lxH).\nExpected %8lxH (NTSTATUS %8lxH)", l_lResult, MapWinErrorToNtStatus(l_lResult), ERROR_IO_PENDING, MapWinErrorToNtStatus(ERROR_IO_PENDING) );
TestEnd();
l_bWaitForAbsent = TRUE; TestStart("%2d. Cold reset card", l_lTestNo++); l_uStatus = in_CReader.ColdResetCard(); TEST_CHECK_SUCCESS("ColdReset", l_uStatus) l_uStateExpected = SCARD_NEGOTIABLE;
TestEnd();
if (TestFailed()) {
return; } break;
case SCARD_NEGOTIABLE: TestCheck( l_bPoweredDown == FALSE, "Invalid reader state.\nCurrent state = %d\nExpected state = %d", l_uState, SCARD_PRESENT );
TestCheck( l_uStateExpected > SCARD_ABSENT, "Invalid reader state.\nCurrent state = %d\nExpected state <= %d", l_uState, l_uStateExpected );
TestEnd();
if (TestFailed()) {
return; }
TestStart("%2d. Set protocol to T0 | T1", l_lTestNo++);
l_uStatus = in_CReader.SetProtocol( SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1 );
TestCheck( l_uStatus == ERROR_SUCCESS, "Protocol selection failed with error %lxh", GetLastError() ); TestEnd();
if (TestFailed()) {
return; } l_uStateExpected = SCARD_SPECIFIC; break;
case SCARD_SPECIFIC: TestCheck( l_bPoweredDown == FALSE, "Invalid reader state.\nCurrent state = %d\nExpected state = %d", l_uState, SCARD_PRESENT );
TestCheck( l_uStateExpected > SCARD_ABSENT, "Invalid reader state.\nReturned %d\nExpected < %d", l_uState, l_uStateExpected );
TestEnd();
if (TestFailed()) {
return; }
TestStart("%2d. IOCTL_SMARTCARD_POWER (SCARD_POWER_DOWN)", l_lTestNo++); l_uMinorIoctl = SCARD_POWER_DOWN; SetLastError(0); l_bResult = DeviceIoControl ( l_hReader, IOCTL_SMARTCARD_POWER, &l_uMinorIoctl, sizeof(l_uMinorIoctl), NULL, 0, &l_uReplyLength, &l_Ovr );
if (l_bResult == FALSE && GetLastError() == ERROR_IO_PENDING) {
SetLastError(0);
l_bResult = GetOverlappedResult( l_hReader, &l_Ovr, &l_uReplyLength, TRUE ); }
l_lResult = GetLastError();
TEST_CHECK_SUCCESS("IOCTL_SMARTCARD_POWER failed", l_lResult); TestEnd();
l_uStateExpected = SCARD_PRESENT; l_bPoweredDown = TRUE; break;
default: TestCheck( FALSE, "Reader returned invalid state %d", l_uState ); TestEnd(); return; } } }
void PowerManagementTest( CReader &in_CReader, ULONG in_uWaitTime ) { LONG l_lResult; ULONG l_uState, l_uPrevState, l_uRepeat; ULONG l_uDuration = 30;
if (in_uWaitTime > 30 && in_uWaitTime < 120) {
l_uDuration = in_uWaitTime; }
LogMessage("============================="); LogMessage("Part E: Power Management Test"); LogMessage("=============================");
LogMessage("Note: Each test cycle takes %ld seconds!", l_uDuration); LogMessage(" << %s", REMOVE_CARD); in_CReader.WaitForCardRemoval();
LogMessage("Test 1: DO NOT INSERT smart card during hibernate mode"); TestStart("Card out / card out - Hibernate now");
l_lResult = in_CReader.StartWaitForCardInsertion(); l_lResult = in_CReader.GetState(&l_uPrevState);
for (l_uRepeat = 0; l_uRepeat < l_uDuration; l_uRepeat++) {
l_lResult = in_CReader.GetState(&l_uState);
LONG l_uGoal = clock() + CLOCKS_PER_SEC; while(l_uGoal > clock()) ; printf("\x08\x08%2ld", l_uDuration - l_uRepeat); } printf("\x08\x08 ");
l_lResult = in_CReader.FinishWaitForCard(FALSE);
TestCheck( l_lResult == ERROR_IO_INCOMPLETE, "GetOverlappedResult failed\nReturned %8lx\nExpected %8lx", l_lResult, ERROR_IO_INCOMPLETE );
TestEnd();
TestStart("%s", INSERT_CARD); l_lResult = in_CReader.FinishWaitForCard(TRUE); TEST_CHECK_SUCCESS("Reader failed card insertion", l_lResult); TestEnd();
TestStart("Checking reader status"); l_lResult = in_CReader.GetState(&l_uState); TEST_CHECK_SUCCESS("Reader failed IOCTL_SMARTCARD_GET_STATE", l_lResult);
TestCheck( l_uState > SCARD_ABSENT, "Invalid reader state.\nReturned %d\nExpected > %d", l_uState, SCARD_ABSENT ); TestEnd();
//
// Test 2
//
LogMessage("Test 2: REMOVE smart card DURING hibernate mode"); TestStart("Card in / card out - Hibernate now");
l_lResult = in_CReader.StartWaitForCardRemoval(); l_lResult = in_CReader.GetState(&l_uPrevState);
for (l_uRepeat = 0; l_uRepeat < l_uDuration; l_uRepeat++) {
l_lResult = in_CReader.GetState(&l_uState);
LONG l_uGoal = clock() + CLOCKS_PER_SEC; while(l_uGoal > clock()) ; printf("\x08\x08%2ld", l_uDuration - l_uRepeat); } printf("\x08\x08 ");
l_lResult = in_CReader.FinishWaitForCard(FALSE);
TEST_CHECK_SUCCESS( "GetOverlappedResult failed", l_lResult );
TestEnd();
TestStart("Checking reader status"); l_lResult = in_CReader.GetState(&l_uState); TEST_CHECK_SUCCESS("Reader failed IOCTL_SMARTCARD_GET_STATE", l_lResult);
TestCheck( l_uState == SCARD_ABSENT, "Invalid reader state.\nReturned %d\nExpected %d", l_uState, SCARD_ABSENT ); TestEnd();
LogMessage(" >> %s", INSERT_CARD); in_CReader.WaitForCardInsertion();
//
// Test 3
//
LogMessage("Test 3: DO NOT REMOVE smart card during hibernate mode"); TestStart("Card in / card in - Hibernate now");
l_lResult = in_CReader.StartWaitForCardRemoval(); l_lResult = in_CReader.GetState(&l_uPrevState);
for (l_uRepeat = 0; l_uRepeat < l_uDuration; l_uRepeat++) {
l_lResult = in_CReader.GetState(&l_uState);
LONG l_uGoal = clock() + CLOCKS_PER_SEC; while(l_uGoal > clock()) ; printf("\x08\x08%2ld", l_uDuration - l_uRepeat); } printf("\x08\x08 ");
l_lResult = in_CReader.FinishWaitForCard(FALSE);
TEST_CHECK_SUCCESS( "GetOverlappedResult failed", l_lResult );
TestEnd();
TestStart("Checking reader status"); l_lResult = in_CReader.GetState(&l_uState); TEST_CHECK_SUCCESS("Reader failed IOCTL_SMARTCARD_GET_STATE", l_lResult);
TestCheck( l_uState >= SCARD_PRESENT, "Invalid reader state.\nReturned %d\nExpected > %d", l_uState, SCARD_ABSENT ); TestEnd();
LogMessage(" << %s", REMOVE_CARD); in_CReader.WaitForCardRemoval();
//
// Test 4
//
LogMessage("Test 4: INSERT smart card DURING hibernate mode"); TestStart("Card out / card in - Hibernate now");
l_lResult = in_CReader.StartWaitForCardInsertion(); l_lResult = in_CReader.GetState(&l_uPrevState);
for (l_uRepeat = 0; l_uRepeat < l_uDuration; l_uRepeat++) {
l_lResult = in_CReader.GetState(&l_uState);
LONG l_uGoal = clock() + CLOCKS_PER_SEC; while(l_uGoal > clock()) ; printf("\x08\x08%2ld", l_uDuration - l_uRepeat); } printf("\x08\x08 "); l_lResult = in_CReader.FinishWaitForCard(FALSE);
TEST_CHECK_SUCCESS( "GetOverlappedResult failed", l_lResult );
TestEnd();
TestStart("Checking reader status"); l_lResult = in_CReader.GetState(&l_uState); TEST_CHECK_SUCCESS("Reader failed IOCTL_SMARTCARD_GET_STATE", l_lResult);
TestCheck( l_uState >= SCARD_PRESENT, "Invalid reader state.\nReturned %d\nExpected > %d", l_uState, SCARD_ABSENT ); TestEnd(); }
class CArgv {
int m_iArgc; char **m_pArgv; BOOL *m_pfRef;
public:
CArgv(int in_iArgc, char **in_pArgv);
int OptionExist(PCHAR);
PCHAR ParameterExist(PCHAR);
PCHAR CheckParameters(CString);
PCHAR CArgv::ParameterUnused(void); };
CArgv::CArgv( int in_iArgc, char **in_pArgv ) { m_iArgc = in_iArgc; m_pArgv = in_pArgv; m_pfRef = new BOOL[in_iArgc]; memset(m_pfRef, 0, sizeof(BOOL) * in_iArgc); }
CArgv::OptionExist( PCHAR in_pchParameter ) { for (int i = 0; i < m_iArgc; i++) {
if (m_pArgv[i][0] == '-' || m_pArgv[i][0] == '/') {
int j = 1;
while (m_pArgv[i][j] && m_pArgv[i][j] != ' ') {
if (strncmp(m_pArgv[i] + j, in_pchParameter, strlen(m_pArgv[i] + j)) == 0) {
m_pfRef[i] = TRUE; return i; }
j++; } } }
return 0; }
PCHAR CArgv::ParameterExist( PCHAR in_pchParameter ) { if (int i = OptionExist(in_pchParameter)) {
m_pfRef[i + 1] = TRUE; return m_pArgv[i + 1]; }
return NULL; }
PCHAR CArgv::CheckParameters( CString in_CParameters ) /*++
Routine Description: Checks if the command line includes in invalid/unknown parameter
--*/ { int i, l_iPos;
for (i = 1; i < m_iArgc; i++) {
if ((l_iPos = in_CParameters.Find(m_pArgv[i])) == -1) {
return m_pArgv[i]; }
if (l_iPos + 3 < in_CParameters.GetLength() && in_CParameters[l_iPos + 3] == '*') {
// skip the next parameter
i += 1; } } return NULL; }
PCHAR CArgv::ParameterUnused( void ) { int i;
for (i = 1; i < m_iArgc; i++) {
if (m_pfRef[i] == FALSE) {
return m_pArgv[i]; } } return NULL; }
CString & GetOperatingSystem( void ) { static CString l_COperatingSystem; OSVERSIONINFO VersionInformation;
if (l_COperatingSystem.GetLength() == 0) {
VersionInformation.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (GetVersionEx(&VersionInformation) == FALSE) {
l_COperatingSystem += "Unknown";
} else {
if (VersionInformation.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
if (VersionInformation.dwMinorVersion == 0) {
l_COperatingSystem += OS_WIN95;
} else {
l_COperatingSystem += OS_WIN98; }
} else if (VersionInformation.dwPlatformId == VER_PLATFORM_WIN32_NT) {
if (VersionInformation.dwMajorVersion <= 4) {
l_COperatingSystem += OS_WINNT4;
} else {
l_COperatingSystem += OS_WINNT5; }
} else {
l_COperatingSystem += "Unknown"; } } }
return l_COperatingSystem; }
CString & SelectReader( void ) { CReaderList l_CReaderList; ULONG l_uIndex, l_uReader; ULONG l_uNumReaders = l_CReaderList.GetNumReaders(); static CString l_CEmpty("");
if (l_uNumReaders == 0) {
return l_CEmpty; }
if (l_uNumReaders == 1) {
return l_CReaderList.GetDeviceName(0); }
CString l_CLetter;
printf("\n"); printf(" Vendor IfdType Type\n"); printf(" -----------------------------------------------------\n");
for (l_uIndex = 0; l_uIndex < l_uNumReaders; l_uIndex++) {
INT l_iLetterPos; INT l_iLength = l_CReaderList.GetVendorName(l_uIndex).GetLength(); CString l_CVendorName = l_CReaderList.GetVendorName(l_uIndex);
for (l_iLetterPos = 0; l_iLetterPos < l_CVendorName.GetLength(); l_iLetterPos++) {
CHAR l_chLetter = l_CVendorName[l_iLetterPos];
if (l_chLetter == ' ' || l_chLetter == 'x') {
continue; }
if (l_CLetter.Find(l_chLetter) == -1) {
l_CLetter += l_chLetter; break; } } if (l_iLetterPos >= l_iLength) {
l_CVendorName += (CHAR) (l_uIndex + '0') ; l_iLetterPos = l_iLength; }
printf( " %s[%c]%-*s %-20s %8s\n", (LPCSTR) l_CVendorName.Left(l_iLetterPos), l_CVendorName[l_iLetterPos], 20 - l_iLetterPos, l_CVendorName.Right(l_iLength - l_iLetterPos - 1), (LPCSTR) l_CReaderList.GetIfdType(l_uIndex), (LPCSTR) l_CReaderList.GetPnPType(l_uIndex) ); }
putchar('\n'); do {
printf("\rSelect reader: \010");
CHAR l_chInput = (CHAR) _getche(); if (l_chInput == 3) {
exit(-1); }
l_uReader = l_CLetter.Find(l_chInput);
} while(l_uReader == -1);
printf("\n");
return l_CReaderList.GetDeviceName(l_uReader); }
CString SelectReader( CString &in_CVendorName ) { CReaderList l_CReaderList; ULONG l_uIndex; ULONG l_uNumReaders = l_CReaderList.GetNumReaders(); CString l_CVendorName = in_CVendorName;
l_CVendorName.MakeLower();
for (l_uIndex = 0; l_uIndex < l_uNumReaders; l_uIndex++) {
CString l_CVendorListName = l_CReaderList.GetVendorName(l_uIndex); l_CVendorListName.MakeLower();
if (l_CVendorListName.Find(l_CVendorName) != -1) {
return l_CReaderList.GetDeviceName(l_uIndex); } }
return CString(""); }
//**********************************************************************
//
// StopService()
//
// PURPOSE : This function attempts to stop a service. It will fail
// the service has any dependent services.
// It also allows a timeout
// value to be passed, to prevent a scenario in which a
// service shutdown hangs, and in turn the application
// stopping the service hangs.
//
// PARAMETERS: hSCM - open handle to the service control manager
// hService - open handle to the service to be stopped
// dwTimeout - maximum time (in milliseconds) to wait
// for the service and its dependencies to stop
//
// RETURN VALUE: TRUE if the service is successfully stopped
//
//**********************************************************************
BOOL StopService( SC_HANDLE hSCM, SC_HANDLE hService, DWORD dwTimeout ) {
SERVICE_STATUS ss; DWORD dwStartTime = GetTickCount();
// Make sure the service is not already stopped
if ( !QueryServiceStatus( hService, &ss ) ) return FALSE;
if ( ss.dwCurrentState == SERVICE_STOPPED ) return FALSE;
// If a stop is pending, just wait for it
while ( ss.dwCurrentState == SERVICE_STOP_PENDING ) {
Sleep( 5000 ); if ( !QueryServiceStatus( hService, &ss ) ) return FALSE;
if ( ss.dwCurrentState == SERVICE_STOPPED ) return FALSE;
if ( GetTickCount() - dwStartTime > dwTimeout ) return FALSE; }
// Send a stop code to service
if ( !ControlService( hService, SERVICE_CONTROL_STOP, &ss ) ) return FALSE;
// Wait for the service to stop
while ( ss.dwCurrentState != SERVICE_STOPPED ) {
Sleep( 5000 ); if ( !QueryServiceStatus( hService, &ss ) ) return FALSE;
if ( ss.dwCurrentState == SERVICE_STOPPED ) break;
if ( GetTickCount() - dwStartTime > dwTimeout ) return FALSE; }
// Return success
return TRUE; }
__cdecl main( int argc, char* argv[] ) { CArgv l_CArgv(argc, argv); BOOL l_bSuccess, l_fInvalidParameter = FALSE; BOOL l_bStoppedScardsvr = FALSE; // true==> we succesfully stoped scardsvr service
SC_HANDLE l_hSCM = NULL; SC_HANDLE l_hService = NULL; LogMessage("Smart Card Reader Test Suite"); LogMessage("Version 2.0.5"); LogMessage("Copyright(c) Microsoft Corporation 1997 - 1999");
if(PCHAR l_pchArgv = l_CArgv.CheckParameters("-d -e -h -m -r * -sa -sb -sc -sd -se -t * -v * -w *")) {
LogMessage("Invalid Parameter '%s'", l_pchArgv); l_fInvalidParameter = TRUE; }
if (l_fInvalidParameter ||
l_CArgv.OptionExist("h")) {
LogMessage("IfdTest [-d] [-m] [-r name] [-sa] [-sb] [-sc] [-sd] [-se] [-ss] [-w sec] [-t test] [-v name]\n"); LogMessage(" -d dumps all i/o"); LogMessage(" -e ends (stops) scardsvr service"); LogMessage(" -m manual test"); LogMessage(" -r name opens reader using device name"); LogMessage(" -sa skips card monitor test"); LogMessage(" -sb skips general reader test"); LogMessage(" -sc skips resource manager simulation"); LogMessage(" -sd skips card tests"); LogMessage(" -se skips power management tests"); LogMessage(" -v name opens reader using vendor name"); LogMessage(" -t test runs only specific card test in part d"); LogMessage(" -w sec runs power management test using specified waiting time"); exit(-1); }
static CReader l_CReader; CString l_CDeviceName;
//
// sandysp 5/9/01: stop scardsvr service because open will fail if it's running
//
if (l_CArgv.OptionExist("e")) { l_hSCM = OpenSCManager( NULL, NULL, SC_MANAGER_CONNECT ); if (l_hSCM) {
// Open the specified service
l_hService = OpenService( l_hSCM, "scardsvr", SERVICE_STOP | SERVICE_START | SERVICE_QUERY_STATUS ); if (l_hService) { // Try to stop the service, specifying a 30 second timeout
l_bStoppedScardsvr = StopService( l_hSCM, l_hService, 30000 ) ; } } }
if (PCHAR l_pchReader = l_CArgv.ParameterExist("r")) {
l_CDeviceName = CString("\\\\.\\") + CString(l_pchReader);
} else if (PCHAR l_pchVendorName = l_CArgv.ParameterExist("v")) {
CReaderList l_CReaderList; l_CDeviceName = SelectReader(CString(l_pchVendorName));
} else {
CReaderList l_CReaderList; l_CDeviceName = SelectReader(); }
if (l_CDeviceName == "") {
LogMessage("No reader found"); exit (-1); } l_bSuccess = l_CReader.Open(l_CDeviceName);
LogMessage("."); if (l_bSuccess == FALSE) {
LogMessage("Can't open smart card reader"); exit (-1); }
if (l_CArgv.OptionExist("d")) {
l_CReader.SetDump(TRUE); }
void ManualTest(CReader &in_CReader); if (l_CArgv.OptionExist("m")) {
ManualTest(l_CReader); }
CCardProvider l_CCardProvider;
LogOpen("ifdtest");
time_t l_osBinaryTime; time( &l_osBinaryTime ); CTime l_CTime( l_osBinaryTime );
LogMessage("Vendor: %s", l_CReader.GetVendorName()); LogMessage("Reader: %s", l_CReader.GetIfdType()); LogMessage( "Date: %d/%02d/%02d", l_CTime.GetMonth(), l_CTime.GetDay(), l_CTime.GetYear() ); LogMessage( "Time: %d:%02d", l_CTime.GetHour(), l_CTime.GetMinute() ); LogMessage("OS: %s", (LPCSTR) GetOperatingSystem());
//
// Check if the reader properly supports
// card insertion and removal
//
if (l_CArgv.OptionExist("sa")) {
LogMessage("================================="); LogMessage("Part A: Card monitor test skipped"); LogMessage("=================================");
} else {
CheckCardMonitor(l_CReader); }
if (l_CArgv.OptionExist("sb")) {
LogMessage("==========================="); LogMessage("Part B: Reader test skipped"); LogMessage("===========================");
} else {
CheckReader(l_CReader); }
if (l_CArgv.OptionExist("sc")) {
LogMessage("==========================================="); LogMessage("Part C: Resource Manager Simulation skipped"); LogMessage("===========================================");
} else {
// Check res manager behavior
SimulateResMngr(l_CReader); }
if (l_CArgv.OptionExist("sd")) {
LogMessage("========================================"); LogMessage("Part D: Smart Card Provider Test skipped"); LogMessage("========================================");
} else {
ULONG l_uTestNo = 0; PCHAR l_pchTestNo;
if (l_pchTestNo = l_CArgv.ParameterExist("t")) {
// The user wants us to run only one test
l_uTestNo = atoi(l_pchTestNo); }
while (l_CCardProvider.CardsUntested()) {
LogMessage("================================"); LogMessage("Part D: Smart Card Provider Test"); LogMessage("================================");
LogMessage("Insert any of the following PC/SC Compliance Test Cards:"); l_CCardProvider.ListUntestedCards();
LogMessage(" >> %s", INSERT_CARD); if (l_CReader.WaitForCardInsertion() != ERROR_SUCCESS) {
LogMessage("Reader failed card insertion monitor"); return -1; }
// Reset the card
if (l_CReader.ColdResetCard() != ERROR_SUCCESS) {
LogMessage("Unable to reset smart card");
} else {
// Try to run tests with this card
l_CCardProvider.CardTest(l_CReader, l_uTestNo);
if (l_uTestNo != 0) {
// Quit the program if we only run one test.
return 0; } }
LogMessage(" << %s", REMOVE_CARD); if (l_CReader.WaitForCardRemoval() != ERROR_SUCCESS) {
LogMessage("Reader failed card removal monitor"); return -1; } } }
if (GetOperatingSystem() == OS_WINNT5) {
if (l_CArgv.OptionExist("se")) {
LogMessage("====================================="); LogMessage("Part E: Power Management Test skipped"); LogMessage("=====================================");
} else {
ULONG l_uWaitTime = 0;
if (PCHAR l_pchWaitTime = l_CArgv.ParameterExist("w")) {
// The user wants us to run only one test
l_uWaitTime = atoi(l_pchWaitTime); }
PowerManagementTest(l_CReader, l_uWaitTime); } }
//
// Sandysp 5/9/01: restart smart card reader service if we stopped it
//
if (l_bStoppedScardsvr) { StartService( l_hService, 0, NULL ); } if ( l_hService ) CloseServiceHandle( l_hService );
if ( l_hSCM ) CloseServiceHandle( l_hSCM );
LogMessage("Reader %s the test", (ReaderFailed() ? "failed" : "passed")); return 0; }
|