|
|
/*--
Copyright (c) 1987-1998 Microsoft Corporation Module Name: sclogon.cxx Abstract: Test program for Smart Card Logon Author: 28-Jun-1993 (cliffv) Environment: User mode only. Contains NT-specific code. Requires ANSI C extensions: slash-slash comments, long external names. Revision History: 29-Oct-1998 (larrywin) --*/
//
// Common include files.
//
extern "C" { #include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <ntseapi.h>
#include <ntlsa.h>
#include <windef.h>
#include <winbase.h>
#include <winsvc.h> // Needed for service controller APIs
#include <lmcons.h>
#include <lmerr.h>
#include <lmaccess.h>
#include <lmsname.h>
#include <rpc.h>
#include <stdio.h> // printf
#include <stdlib.h> // strtoul
#include <stddef.h> // 'offset' macro
#include <windows.h>
#include <winnls.h>
#include <iostream.h>
#include <winioctl.h>
#include <tchar.h>
#include <string.h>
} #include <wchar.h>
#include <conio.h>
#include <ctype.h>
extern "C" { #include <netlib.h> // NetpGetLocalDomainId
#include <tstring.h> // NetpAllocWStrFromWStr
#define SECURITY_KERBEROS
#define SECURITY_PACKAGE
#include <security.h> // General definition of a Security Support Provider
#include <secint.h>
#include <kerbcomm.h>
#include <negossp.h>
#include <wincrypt.h>
#include <cryptui.h>
} #include <sclogon.h>
#include <winscard.h>
#include <log.h>
#define MAX_RECURSION_DEPTH 1
#define BUFFERSIZE 200
BOOLEAN QuietMode = FALSE; // Don't be verbose
BOOLEAN DoAnsi = FALSE; ULONG RecursionDepth = 0; CredHandle ServerCredHandleStorage; PCredHandle ServerCredHandle = NULL; LPWSTR g_wszReaderName = new wchar_t[BUFFERSIZE]; // file handle for output file
FILE *outstream;
/*++
PrintMessage:
Simple function to dump text to standard output. Arguments:
lpszFormat - String to dump to standard output --*/
void _cdecl PrintMessage( IN LPSTR lpszFormat, ...) { //
// Helper to do print traces...
//
va_list args; va_start(args, lpszFormat);
int nBuf; char szBuffer[512]; ZeroMemory(szBuffer, sizeof(szBuffer));
nBuf = _vstprintf(szBuffer, lpszFormat, args);
_tprintf(szBuffer); fprintf(outstream, "%s", szBuffer);
OutputDebugStringA(szBuffer); va_end(args); }
/*++
BuildLogonInfo: GetReaderName: GetCardName: GetContainerName: GetCSPName: : Intended for accessing the LogonInformation glob Author: Amanda Matlosz Note: Some of these are made available to outside callers; see sclogon.h --*/ PBYTE BuildSCLogonInfo( LPCTSTR szCard, LPCTSTR szReader, LPCTSTR szContainer, LPCTSTR szCSP) { // No assumptions are made regarding the values of the incoming parameters;
// At this point, it is legal for them all to be empty.
// It is also possible that NULL values are being passed in -- if this is the case,
// they must be replaced with empty strings.
LPCTSTR szCardI = TEXT(""); LPCTSTR szReaderI = TEXT(""); LPCTSTR szContainerI = TEXT(""); LPCTSTR szCSPI = TEXT(""); if (NULL != szCard) { szCardI = szCard; } if (NULL != szReader) { szReaderI = szReader; } if (NULL != szContainer) { szContainerI = szContainer; } if (NULL != szCSP) { szCSPI = szCSP; } //
// Build the LogonInfo glob using strings (or empty strings)
//
DWORD cbLi = offsetof(LogonInfo, bBuffer) + (lstrlen(szCardI) + 1) * sizeof(TCHAR) + (lstrlen(szReaderI) + 1) * sizeof(TCHAR) + (lstrlen(szContainerI) + 1) * sizeof(TCHAR) + (lstrlen(szCSPI) + 1) * sizeof(TCHAR); LogonInfo* pLI = (LogonInfo*)LocalAlloc(LPTR, cbLi); if (NULL == pLI) { return NULL; } pLI->ContextInformation = NULL; pLI->dwLogonInfoLen = cbLi; LPTSTR pBuffer = pLI->bBuffer; pLI->nCardNameOffset = 0; lstrcpy(pBuffer, szCardI); pBuffer += (lstrlen(szCardI)+1); pLI->nReaderNameOffset = (ULONG) (pBuffer-pLI->bBuffer); lstrcpy(pBuffer, szReaderI); pBuffer += (lstrlen(szReaderI)+1); pLI->nContainerNameOffset = (ULONG) (pBuffer-pLI->bBuffer); lstrcpy(pBuffer, szContainerI); pBuffer += (lstrlen(szContainerI)+1); pLI->nCSPNameOffset = (ULONG) (pBuffer-pLI->bBuffer); lstrcpy(pBuffer, szCSPI); pBuffer += (lstrlen(szCSPI)+1); // _ASSERTE(cbLi == (DWORD)((LPBYTE)pBuffer - (LPBYTE)pLI));
return (PBYTE)pLI; }
void FreeErrorString( LPCTSTR szErrorString) { if (NULL != szErrorString) LocalFree((LPVOID)szErrorString); }
LPTSTR ErrorString( IN DWORD dwError ) { DWORD dwLen = 0; LPTSTR szErrorString = NULL;
dwLen = FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, (DWORD)dwError, LANG_NEUTRAL, (LPTSTR)&szErrorString, 0, NULL);
return szErrorString; }
HANDLE FindAndOpenWinlogon( VOID ) { PSYSTEM_PROCESS_INFORMATION SystemInfo ; PSYSTEM_PROCESS_INFORMATION Walk ; NTSTATUS Status ; UNICODE_STRING Winlogon ; HANDLE Process ;
SystemInfo = (PSYSTEM_PROCESS_INFORMATION)LocalAlloc( LMEM_FIXED, sizeof( SYSTEM_PROCESS_INFORMATION ) * 1024 );
if ( !SystemInfo ) { return NULL ; }
Status = NtQuerySystemInformation( SystemProcessInformation, SystemInfo, sizeof( SYSTEM_PROCESS_INFORMATION ) * 1024, NULL );
if ( !NT_SUCCESS( Status ) ) { return NULL ; }
RtlInitUnicodeString( &Winlogon, L"winlogon.exe" );
Walk = SystemInfo ;
while ( RtlCompareUnicodeString( &Walk->ImageName, &Winlogon, TRUE ) != 0 ) { if ( Walk->NextEntryOffset == 0 ) { Walk = NULL ; break; }
Walk = (PSYSTEM_PROCESS_INFORMATION) ((PUCHAR) Walk + Walk->NextEntryOffset );
}
if ( !Walk ) { LocalFree( SystemInfo ); return NULL ; }
Process = OpenProcess( PROCESS_QUERY_INFORMATION, FALSE, HandleToUlong(Walk->UniqueProcessId) );
LocalFree( SystemInfo );
return Process ;
}
NTSTATUS TestScLogonRoutine( IN ULONG Count, IN LPSTR Pin ) { NTSTATUS Status; PKERB_SMART_CARD_LOGON LogonInfo; ULONG LogonInfoSize = sizeof(KERB_SMART_CARD_LOGON); BOOLEAN WasEnabled; STRING PinString; STRING Name; ULONG Dummy; HANDLE LogonHandle = NULL; ULONG PackageId; TOKEN_SOURCE SourceContext; PKERB_INTERACTIVE_PROFILE Profile = NULL; ULONG ProfileSize; LUID LogonId; HANDLE TokenHandle = NULL; QUOTA_LIMITS Quotas; NTSTATUS SubStatus; WCHAR UserNameString[100]; ULONG NameLength = 100; PUCHAR Where; ULONG Index; HANDLE ScHandle = NULL; PBYTE ScLogonInfo = NULL; ULONG ScLogonInfoSize; ULONG WaitResult = 0; SCARDCONTEXT hContext = NULL; LONG lCallReturn = -1; LPTSTR szReaders = NULL; LPTSTR pchReader = NULL; LPTSTR mszCards = NULL; LPTSTR szLogonCard = NULL; LPTSTR szCSPName = NULL; BYTE bSLBAtr[] = {0x3b,0xe2,0x00,0x00,0x40,0x20,0x49,0x06}; BYTE bGEMAtr[] = {0x3b,0x27,0x00,0x80,0x65,0xa2,0x00,0x01,0x01,0x37}; DWORD dwReadersLen = SCARD_AUTOALLOCATE; DWORD dwCardsLen = SCARD_AUTOALLOCATE; DWORD dwCSPLen = SCARD_AUTOALLOCATE; SCARD_READERSTATE rgReaderStates[MAXIMUM_SMARTCARD_READERS]; // not necessarily max for pnp readers
LONG nIndex; LONG nCnReaders; BOOL fFound = FALSE; SYSTEMTIME StartTime, DoneTime; SYSTEMTIME stElapsed; FILETIME ftStart, ftDone, *pftStart = &ftStart, *pftDone = &ftDone; LARGE_INTEGER liStart, liDone, *pliStart = &liStart, *pliDone = &liDone; LARGE_INTEGER liAccumulatedTime, liSplitTime, *pliAccumulatedTime = &liAccumulatedTime, *pliSplitTime = &liSplitTime; FILETIME ftAccumulatedTime, *pftAccumulatedTime = &ftAccumulatedTime; SYSTEMTIME stAccumulatedTime; LPWSTR buffer = new wchar_t[BUFFERSIZE]; int j; memset(buffer, 0, BUFFERSIZE); liAccumulatedTime.QuadPart = 0; // get a ResMgr context
lCallReturn = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &hContext); if ( SCARD_S_SUCCESS != lCallReturn) { swprintf(buffer, L"Failed to initialize context: 0x%x\n", lCallReturn); PrintMessage("%S",buffer); memset(buffer, 0, sizeof(buffer)); return (NTSTATUS)lCallReturn; } // list all readers
lCallReturn = SCardListReaders(hContext, SCARD_ALL_READERS, (LPTSTR)&szReaders, &dwReadersLen); if (SCARD_S_SUCCESS != lCallReturn) { swprintf(buffer, L"Failed to list readers on the system: 0x%x\n", lCallReturn); PrintMessage("%S",buffer); memset(buffer, 0, sizeof(buffer)); return (NTSTATUS)lCallReturn; } else if ((0 == dwReadersLen) || (NULL == szReaders) || (0 == *szReaders)) { lCallReturn = SCARD_E_UNKNOWN_READER; // Or some such error
if (NULL != szReaders) SCardFreeMemory(hContext, (LPVOID)szReaders); swprintf(buffer, L"Failed to identify a reader on the system: 0x%x\n", lCallReturn); PrintMessage("%S",buffer); memset(buffer, 0, sizeof(buffer)); return (NTSTATUS)lCallReturn; } // list cards
lCallReturn = SCardListCards(hContext, NULL, NULL, 0, (LPTSTR)&mszCards, &dwCardsLen); if ( SCARD_S_SUCCESS != lCallReturn) { printf("Failed to list cards in the system: 0x%x\n", lCallReturn); if (NULL != szReaders) SCardFreeMemory(hContext, (LPVOID)szReaders); if (NULL != mszCards ) SCardFreeMemory(hContext, (LPVOID)mszCards); swprintf(buffer, L"Failed to identify a card on the system: 0x%x\n", lCallReturn); PrintMessage("%S",buffer); memset(buffer, 0, sizeof(buffer)); return (NTSTATUS)lCallReturn; } // use the list of readers to build a readerstate array
nIndex = 0; if (0 != wcslen(g_wszReaderName)) { // use the reader specified in the command line
rgReaderStates[nIndex].szReader = (const unsigned short *)g_wszReaderName; rgReaderStates[nIndex].dwCurrentState = SCARD_STATE_UNAWARE; nCnReaders = 1; } else { pchReader = szReaders; while (0 != *pchReader) { rgReaderStates[nIndex].szReader = pchReader; rgReaderStates[nIndex].dwCurrentState = SCARD_STATE_UNAWARE; pchReader += lstrlen(pchReader)+1; nIndex++; if (MAXIMUM_SMARTCARD_READERS == nIndex) break; } nCnReaders = nIndex; } // find a reader with one of the listed cards, or the specified card, present
lCallReturn = SCardLocateCards(hContext, mszCards, rgReaderStates, nCnReaders); if ( SCARD_S_SUCCESS != lCallReturn) { if (NULL != szReaders) SCardFreeMemory(hContext, (LPVOID)szReaders); if (NULL != mszCards ) SCardFreeMemory(hContext, (LPVOID)mszCards); swprintf(buffer, L"Failed to locate a smart card for logon: 0x%x\n", lCallReturn); PrintMessage("%S",buffer); memset(buffer, 0, sizeof(buffer)); return (NTSTATUS)lCallReturn; } // find the reader containing the requested card
for (nIndex=0; nIndex<nCnReaders && FALSE == fFound; nIndex++) { if (rgReaderStates[nIndex].dwEventState & SCARD_STATE_ATRMATCH) { // reader found
fFound = TRUE; break; } } if (FALSE == fFound) { lCallReturn = SCARD_E_NO_SMARTCARD; // or some such error
if (NULL != szReaders) SCardFreeMemory(hContext, (LPVOID)szReaders); if (NULL != mszCards ) SCardFreeMemory(hContext, (LPVOID)mszCards); swprintf(buffer, L"No smart card in any reader: 0x%x\n", lCallReturn); PrintMessage("%S",buffer); memset(buffer, 0, sizeof(buffer)); return (NTSTATUS)lCallReturn; } else { // get the name of the card found
dwCardsLen = SCARD_AUTOALLOCATE; lCallReturn = SCardListCards(hContext, rgReaderStates[nIndex].rgbAtr, NULL, 0, (LPTSTR)&szLogonCard, &dwCardsLen); if ( SCARD_S_SUCCESS != lCallReturn ) { if (NULL != szReaders) SCardFreeMemory(hContext, (LPVOID)szReaders); if (NULL != mszCards ) SCardFreeMemory(hContext, (LPVOID)mszCards); if (NULL != szLogonCard ) SCardFreeMemory(hContext, (LPVOID)szLogonCard); swprintf(buffer, L"Failed to get name of card in reader: 0x%x\n", lCallReturn); PrintMessage("%S",buffer); memset(buffer, 0, sizeof(buffer)); return (NTSTATUS)lCallReturn; } } // get the csp provider name for the card
lCallReturn = SCardGetCardTypeProviderName(hContext, szLogonCard, SCARD_PROVIDER_CSP, (LPTSTR)&szCSPName, &dwCSPLen); if ( SCARD_S_SUCCESS != lCallReturn) { if (NULL != szReaders) SCardFreeMemory(hContext, (LPVOID)szReaders); if (NULL != mszCards ) SCardFreeMemory(hContext, (LPVOID)mszCards); if (NULL != szCSPName) SCardFreeMemory(hContext, (LPVOID)szCSPName); if (NULL != szLogonCard ) SCardFreeMemory(hContext, (LPVOID)szLogonCard); swprintf(buffer, L"Failed to locate smart card crypto service provider: 0x%x\n", lCallReturn); PrintMessage("%S",buffer); memset(buffer, 0, sizeof(buffer)); return (NTSTATUS)lCallReturn; } ScLogonInfo = BuildSCLogonInfo(szLogonCard, rgReaderStates[nIndex].szReader, TEXT(""), // use default container
szCSPName ); //
// We should now have logon info.
//
if (NULL != szReaders) SCardFreeMemory(hContext, (LPVOID)szReaders); if (NULL != mszCards ) SCardFreeMemory(hContext, (LPVOID)mszCards); if (NULL != szCSPName) SCardFreeMemory(hContext, (LPVOID)szCSPName); if (NULL != szLogonCard ) SCardFreeMemory(hContext, (LPVOID)szLogonCard); j = swprintf(buffer, L"Reader : %s\n", GetReaderName(ScLogonInfo)); j += swprintf(buffer + j, L"Card : %s\n", GetCardName(ScLogonInfo)); j += swprintf(buffer + j, L"CSP : %s\n", GetCSPName(ScLogonInfo)); PrintMessage("%S",buffer); memset(buffer, 0, sizeof(buffer));
// perform sclogon
if (ScLogonInfo == NULL) { swprintf(buffer, L"Failed to get logon info!\n"); PrintMessage("%S",buffer); memset(buffer, 0, BUFFERSIZE); return (NTSTATUS) -1; } ScLogonInfoSize = ((struct LogonInfo *) ScLogonInfo)->dwLogonInfoLen; Status = ScHelperInitializeContext( ScLogonInfo, ScLogonInfoSize ); if (!NT_SUCCESS(Status)) { swprintf(buffer, L"Failed to initialize helper context: 0x%x\n",Status); PrintMessage("%S",buffer); memset(buffer, 0, BUFFERSIZE); return (NTSTATUS)Status; } ScHelperRelease(ScLogonInfo); RtlInitString( &PinString, Pin ); LogonInfoSize += (PinString.Length+1 ) * sizeof(WCHAR) + ScLogonInfoSize; LogonInfo = (PKERB_SMART_CARD_LOGON) LocalAlloc(LMEM_ZEROINIT, LogonInfoSize); LogonInfo->MessageType = KerbSmartCardLogon; Where = (PUCHAR) (LogonInfo + 1); LogonInfo->Pin.Buffer = (LPWSTR) Where; LogonInfo->Pin.MaximumLength = (USHORT) LogonInfoSize; RtlAnsiStringToUnicodeString( &LogonInfo->Pin, &PinString, FALSE ); Where += LogonInfo->Pin.Length + sizeof(WCHAR); LogonInfo->CspDataLength = ScLogonInfoSize; LogonInfo->CspData = Where; RtlCopyMemory( LogonInfo->CspData, ScLogonInfo, ScLogonInfoSize ); Where += ScLogonInfoSize; //
// Turn on the TCB privilege
//
Status = RtlAdjustPrivilege(SE_TCB_PRIVILEGE, TRUE, FALSE, &WasEnabled); if (!NT_SUCCESS(Status)) { swprintf(buffer, L"Failed to adjust privilege: 0x%x\n",Status); PrintMessage("%S",buffer); memset(buffer, 0, BUFFERSIZE); return (NTSTATUS)Status; }
RtlInitString( &Name, "SmartCardLogon" ); Status = LsaRegisterLogonProcess( &Name, &LogonHandle, &Dummy ); if (!NT_SUCCESS(Status)) { swprintf(buffer, L"Failed to register as a logon process: 0x%x\n",Status); PrintMessage("%S",buffer); memset(buffer, 0, BUFFERSIZE); return (NTSTATUS)Status; } strncpy( SourceContext.SourceName, "SmartCardLogon ",sizeof(SourceContext.SourceName) ); NtAllocateLocallyUniqueId( &SourceContext.SourceIdentifier ); RtlInitString( &Name, MICROSOFT_KERBEROS_NAME_A ); Status = LsaLookupAuthenticationPackage( LogonHandle, &Name, &PackageId ); if (!NT_SUCCESS(Status)) { swprintf(buffer, L"Failed to lookup package %Z: 0x%x\n",&Name, Status); PrintMessage("%S",buffer); memset(buffer, 0, BUFFERSIZE); return (NTSTATUS)Status; } //
// Now call LsaLogonUser
//
RtlInitString( &Name, "SmartCardLogon" );
for (Index = 1; Index <= Count ; Index++ ) { swprintf(buffer, L"\nLogon %.6d\n", Index); PrintMessage("%S",buffer); memset(buffer, 0, BUFFERSIZE);
// get start time
GetSystemTime(&StartTime); Status = LsaLogonUser( LogonHandle, &Name, Interactive, PackageId, LogonInfo, LogonInfoSize, NULL, // no token groups
&SourceContext, (PVOID *) &Profile, &ProfileSize, &LogonId, &TokenHandle, &Quotas, &SubStatus );
// get done time
GetSystemTime(&DoneTime);
// convert systemtime to filetime
SystemTimeToFileTime(&StartTime, &ftStart); SystemTimeToFileTime(&DoneTime, &ftDone); // copy filetime to large int
CopyMemory(pliStart, pftStart, 8); CopyMemory(pliDone, pftDone, 8); // diff the large ints and accumulate result
liDone.QuadPart = liDone.QuadPart - liStart.QuadPart; liAccumulatedTime.QuadPart = liAccumulatedTime.QuadPart + liDone.QuadPart; // copy result back to filetime
CopyMemory(pftDone, pliDone, 8); // convert result back to systemtime
FileTimeToSystemTime( (CONST FILETIME *)&ftDone, &stElapsed); // output the result
swprintf(buffer, L"RunTime: %2.2ldm:%2.2lds:%3.3ldms\n", stElapsed.wMinute, stElapsed.wSecond, stElapsed.wMilliseconds); PrintMessage("%S",buffer); memset(buffer, 0, BUFFERSIZE);
if (!NT_SUCCESS(Status)) { j = swprintf(buffer, L"lsalogonuser failed: 0x%x\n",Status); LPTSTR szErrorMessage = ErrorString((DWORD)Status); if (NULL == szErrorMessage) { j += swprintf(buffer + j, L" ErrorMessage: error message not found, check ntstatus.h\n"); } else { j += swprintf(buffer + j, L" ErrorMessage: %S\n", szErrorMessage); } PrintMessage("%S",buffer); memset(buffer, 0, BUFFERSIZE); return (NTSTATUS)Status; } if (!NT_SUCCESS(SubStatus)) { j = swprintf(buffer, L"LsalogonUser failed: substatus = 0x%x\n",SubStatus); LPTSTR szErrorMessage = ErrorString((DWORD)Status); if (NULL == szErrorMessage) { j += swprintf(buffer + j, L" ErrorMessage: error message not found, check ntstatus.h\n"); } else { j += swprintf(buffer + j, L" ErrorMessage: %S", szErrorMessage); } PrintMessage("%S",buffer); memset(buffer, 0, BUFFERSIZE); return (NTSTATUS)SubStatus; } ImpersonateLoggedOnUser( TokenHandle ); GetUserName(UserNameString,&NameLength); j = swprintf(buffer, L"Result: %S", ErrorString((DWORD)Status)); j += swprintf(buffer, L"Username: %ws\n",UserNameString); PrintMessage("%S",buffer); memset(buffer, 0, BUFFERSIZE); RevertToSelf(); NtClose(TokenHandle); LsaFreeReturnBuffer(Profile); Profile = NULL;
// report average every 10th logon
if (0 == Index % 10) { liSplitTime.QuadPart = liAccumulatedTime.QuadPart / Index; CopyMemory(pftAccumulatedTime, pliSplitTime, 8); FileTimeToSystemTime( (CONST FILETIME *)&ftAccumulatedTime, &stAccumulatedTime); swprintf(buffer, L"\nAverage Time after %d Logons: %2.2ldm:%2.2lds:%3.3ldms\n", Index, stAccumulatedTime.wMinute, stAccumulatedTime.wSecond, stAccumulatedTime.wMilliseconds); PrintMessage("%S",buffer); }
Sleep(2000); // let card stack unwind
}
// ouput average results
if ( 1 != Count ) { liAccumulatedTime.QuadPart = liAccumulatedTime.QuadPart / Count; CopyMemory(pftAccumulatedTime, pliAccumulatedTime, 8); FileTimeToSystemTime( (CONST FILETIME *)&ftAccumulatedTime, &stAccumulatedTime); swprintf(buffer, L"\nAverage Logon Time: %2.2ldm:%2.2lds:%3.3ldms\n", stAccumulatedTime.wMinute, stAccumulatedTime.wSecond, stAccumulatedTime.wMilliseconds); PrintMessage("%S", buffer); } return (NTSTATUS)Status; }
VOID PrintKdcName( IN PKERB_INTERNAL_NAME Name ) { ULONG Index; for (Index = 0; Index < Name->NameCount ; Index++ ) { printf(" %wZ ",&Name->Names[Index]); } printf("\n"); }
int __cdecl main( IN int argc, IN char ** argv ) /*++
Routine Description: Drive the NtLmSsp service Arguments: argc - the number of command-line arguments. argv - an array of pointers to the arguments. Return Value: Exit status --*/ { LPSTR argument; int i; ULONG j; ULONG Iterations = 0; LPSTR PinBuffer = new char [81]; LPSTR szReaderBuffer = new char[BUFFERSIZE]; LPSTR EventMachineBuffer = new char [81]; LPWSTR wEventMachineBuffer = new wchar_t[81]; LPWSTR PackageFunction; ULONG ContextReq = 0; WCHAR ContainerName[100]; WCHAR CaName[100]; WCHAR CaLocation[100]; WCHAR ServiceName[100]; NTSTATUS Status = -1; enum { NoAction, #define LOGON_PARAM "/p"
TestLogon, #define ITERATION_PARAM "/i"
#define HELP_PARAM "/?"
//#define EVENT_PARAM "/s"
#define READER_PARAM "/r"
} Action = NoAction;
memset(g_wszReaderName, 0, BUFFERSIZE); memset(szReaderBuffer, 0, BUFFERSIZE);
// open output file
outstream = fopen( "scardbvt.out", "w" ); //
// Loop through the arguments handle each in turn
//
if ( 1 == argc ) {// silent mode
Iterations = 1; Action = TestLogon; printf("Enter your pin number: "); int ch; int j = 0;
ch = _getch();
while (ch != 0x0d) { j += sprintf(PinBuffer + j,"%c", ch); printf("*"); ch = _getch(); }
printf("\n");
} for ( i=1; i<argc; i++ ) { argument = argv[i]; //
// Handle /ConfigureService
//
if ( _strnicmp( argument, LOGON_PARAM, sizeof(LOGON_PARAM)-1 ) == 0 ) { if ( Action != NoAction ) { goto Usage; }
Iterations = 1; Action = TestLogon; if (argc <= i + 1) { goto Usage; }
PinBuffer = argv[++i];
} else if ( _strnicmp( argument, ITERATION_PARAM, sizeof(ITERATION_PARAM) - 1 ) == 0 ) { if (argc <= i + 1) { goto Usage; } Iterations = atoi(argv[++i]);
} /*else if ( _strnicmp( argument, EVENT_PARAM, sizeof(EVENT_PARAM) - 1 ) == 0 ) {
if (argc <= i + 1) { goto Usage; } // save name of machine to which events will be posted
EventMachineBuffer = argv[++i]; wsprintfW(wEventMachineBuffer, L"%S", EventMachineBuffer); SetEventMachine(&wEventMachineBuffer); //Event(PERF_INFORMATION, L"Trying to set machine name\n", 1);
} */ else if ( _strnicmp( argument, HELP_PARAM, sizeof(HELP_PARAM) - 1 ) == 0 ) { goto Usage; } else if ( _strnicmp( argument, READER_PARAM, sizeof(READER_PARAM) - 1 ) == 0 ) { if (argc <= i + 1) { goto Usage; } // get the name of a specified reader
szReaderBuffer = argv[++i]; wsprintfW(g_wszReaderName, L"%S", szReaderBuffer); } else { printf("Invalid parameter : %s\n",argument); goto Usage; } }
//
// Perform the action requested
//
switch ( Action ) { case TestLogon : Status = TestScLogonRoutine( Iterations, PinBuffer ); break;
case NoAction : goto Usage; break; } return Status; Usage: PrintMessage("%s - no parameters, manually enter pin\n", argv[0]); PrintMessage(" optional parameters (if any used, must have /p)\n"); PrintMessage(" /p Pin\n"); PrintMessage(" /i Iterations\n"); // printf(" /s EventMachineName (post events to this machine)\n");
PrintMessage(" /r %cReader Name X%c (registry device name in quotes)\n", '"', '"'); return -1; }
|