You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1928 lines
63 KiB
1928 lines
63 KiB
/*++
|
|
|
|
Copyright (C) Microsoft Corporation, 1996 - 1999
|
|
|
|
Module Name:
|
|
|
|
scTrace
|
|
|
|
Abstract:
|
|
|
|
This program performs analysis on a Calais I/O trace.
|
|
|
|
Author:
|
|
|
|
Doug Barlow (dbarlow) 10/30/1997
|
|
|
|
Environment:
|
|
|
|
Win32
|
|
|
|
Notes:
|
|
|
|
?Notes?
|
|
|
|
--*/
|
|
|
|
#ifndef WIN32_LEAN_AND_MEAN
|
|
#define WIN32_LEAN_AND_MEAN
|
|
#endif
|
|
#include <windows.h>
|
|
#include <stdlib.h>
|
|
#include <iostream.h>
|
|
#include <iomanip.h>
|
|
#include <calcom.h>
|
|
|
|
|
|
//
|
|
// This structure must match the one used by SCardSvr.
|
|
//
|
|
|
|
typedef struct {
|
|
DWORD dwStructLen; // Actual structure length
|
|
SYSTEMTIME StartTime; // Time request was posted
|
|
SYSTEMTIME EndTime; // Time request completed
|
|
DWORD dwProcId; // Process Id
|
|
DWORD dwThreadId; // Thread Id
|
|
HANDLE hDevice; // I/O handle
|
|
DWORD dwIoControlCode; // I/O control code issued
|
|
DWORD nInBuffer; // Offset to input buffer
|
|
DWORD nInBufferSize; // Input buffer size
|
|
DWORD nOutBuffer; // Offset to output buffer
|
|
DWORD nOutBufferSize; // Size of user's receive buffer
|
|
DWORD nBytesReturned; // Actual size of returned data
|
|
DWORD dwStatus; // Returned status code
|
|
// InBuffer and OutBuffer follow.
|
|
} RequestTrace;
|
|
|
|
typedef struct {
|
|
DWORD dwValue;
|
|
LPCTSTR szValue;
|
|
} ValueMap;
|
|
|
|
typedef struct
|
|
{
|
|
SYSTEMTIME stLogTime;
|
|
DWORD dwProcId;
|
|
DWORD dwThreadId;
|
|
} LogStamp;
|
|
|
|
HANDLE g_hCalaisShutdown = NULL;
|
|
|
|
static void
|
|
ShowDriverLog(
|
|
IN LPCTSTR szFile);
|
|
|
|
static void
|
|
ShowApiLog(
|
|
IN LPCTSTR szFile);
|
|
|
|
static void
|
|
dump(
|
|
const BYTE *pbData,
|
|
DWORD cbLen,
|
|
ostream &outStr);
|
|
|
|
static void
|
|
GeneralDump(
|
|
ostream &outStr,
|
|
const RequestTrace *prqTrace);
|
|
|
|
static void
|
|
SendDump(
|
|
ostream &outStr,
|
|
const RequestTrace *prqTrace);
|
|
|
|
static void
|
|
RecvDump(
|
|
ostream &outStr,
|
|
const RequestTrace *prqTrace);
|
|
|
|
static void
|
|
MapValue(
|
|
ostream &outStr,
|
|
DWORD dwValue,
|
|
LPCTSTR szLeader,
|
|
const ValueMap *rgMap);
|
|
|
|
static void
|
|
MaskValue(
|
|
ostream &outStr,
|
|
DWORD dwValue,
|
|
LPCTSTR szLeader,
|
|
const ValueMap *rgMap);
|
|
|
|
static void
|
|
MapInput(
|
|
ostream &outStr,
|
|
const RequestTrace *prqTrace,
|
|
const ValueMap *rgMap);
|
|
|
|
static void
|
|
MapOutput(
|
|
ostream &outStr,
|
|
const RequestTrace *prqTrace,
|
|
const ValueMap *rgMap);
|
|
|
|
static void
|
|
ShowSyntax(
|
|
ostream &outStr);
|
|
|
|
CComObject *
|
|
ReceiveComObject(
|
|
HANDLE hFile);
|
|
|
|
#define PHex(x) TEXT("0x") << hex << setw(8) << setfill(TEXT('0')) << (DWORD)(x)
|
|
#define PDec(x) dec << setw(0) << setfill(TEXT(' ')) << (x)
|
|
#define MAP(x) { x, TEXT(#x) }
|
|
#define PTime(x) dec \
|
|
<< setw(2) << setfill(TEXT('0')) << (x).wHour << TEXT(":") \
|
|
<< setw(2) << setfill(TEXT('0')) << (x).wMinute << TEXT(":") \
|
|
<< setw(2) << setfill(TEXT('0')) << (x).wSecond << TEXT(".") \
|
|
<< setw(3) << setfill(TEXT('0')) << (x).wMilliseconds
|
|
|
|
static const ValueMap rgMapProto[]
|
|
= { MAP(SCARD_PROTOCOL_UNDEFINED), MAP(SCARD_PROTOCOL_T0),
|
|
MAP(SCARD_PROTOCOL_T1), MAP(SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1),
|
|
MAP(SCARD_PROTOCOL_RAW), MAP(SCARD_PROTOCOL_DEFAULT),
|
|
{ 0, NULL } };
|
|
static const ValueMap rgMapIoctl[]
|
|
= { MAP(IOCTL_SMARTCARD_POWER), MAP(IOCTL_SMARTCARD_GET_ATTRIBUTE),
|
|
MAP(IOCTL_SMARTCARD_SET_ATTRIBUTE), MAP(IOCTL_SMARTCARD_CONFISCATE),
|
|
MAP(IOCTL_SMARTCARD_TRANSMIT), MAP(IOCTL_SMARTCARD_EJECT),
|
|
MAP(IOCTL_SMARTCARD_SWALLOW), MAP(IOCTL_SMARTCARD_IS_PRESENT),
|
|
MAP(IOCTL_SMARTCARD_IS_ABSENT), MAP(IOCTL_SMARTCARD_SET_PROTOCOL),
|
|
MAP(IOCTL_SMARTCARD_GET_STATE), MAP(IOCTL_SMARTCARD_GET_LAST_ERROR),
|
|
{ 0, NULL } };
|
|
static const ValueMap rgMapAttr[]
|
|
= { MAP(SCARD_ATTR_VENDOR_NAME), MAP(SCARD_ATTR_VENDOR_IFD_TYPE),
|
|
MAP(SCARD_ATTR_VENDOR_IFD_VERSION), MAP(SCARD_ATTR_VENDOR_IFD_SERIAL_NO),
|
|
MAP(SCARD_ATTR_CHANNEL_ID), MAP(SCARD_ATTR_DEFAULT_CLK),
|
|
MAP(SCARD_ATTR_MAX_CLK), MAP(SCARD_ATTR_DEFAULT_DATA_RATE),
|
|
MAP(SCARD_ATTR_MAX_DATA_RATE), MAP(SCARD_ATTR_MAX_IFSD),
|
|
MAP(SCARD_ATTR_POWER_MGMT_SUPPORT), MAP(SCARD_ATTR_USER_TO_CARD_AUTH_DEVICE),
|
|
MAP(SCARD_ATTR_USER_AUTH_INPUT_DEVICE), MAP(SCARD_ATTR_CHARACTERISTICS),
|
|
MAP(SCARD_ATTR_CURRENT_PROTOCOL_TYPE), MAP(SCARD_ATTR_CURRENT_CLK),
|
|
MAP(SCARD_ATTR_CURRENT_F), MAP(SCARD_ATTR_CURRENT_D),
|
|
MAP(SCARD_ATTR_CURRENT_N), MAP(SCARD_ATTR_CURRENT_W),
|
|
MAP(SCARD_ATTR_CURRENT_IFSC), MAP(SCARD_ATTR_CURRENT_IFSD),
|
|
MAP(SCARD_ATTR_CURRENT_BWT), MAP(SCARD_ATTR_CURRENT_CWT),
|
|
MAP(SCARD_ATTR_CURRENT_EBC_ENCODING), MAP(SCARD_ATTR_EXTENDED_BWT),
|
|
MAP(SCARD_ATTR_ICC_PRESENCE), MAP(SCARD_ATTR_ICC_INTERFACE_STATUS),
|
|
MAP(SCARD_ATTR_CURRENT_IO_STATE), MAP(SCARD_ATTR_ATR_STRING),
|
|
MAP(SCARD_ATTR_ICC_TYPE_PER_ATR), MAP(SCARD_ATTR_ESC_RESET),
|
|
MAP(SCARD_ATTR_ESC_CANCEL), MAP(SCARD_ATTR_ESC_AUTHREQUEST),
|
|
MAP(SCARD_ATTR_MAXINPUT), MAP(SCARD_ATTR_DEVICE_UNIT),
|
|
MAP(SCARD_ATTR_DEVICE_IN_USE), MAP(SCARD_ATTR_DEVICE_FRIENDLY_NAME_A),
|
|
MAP(SCARD_ATTR_DEVICE_SYSTEM_NAME_A), MAP(SCARD_ATTR_DEVICE_FRIENDLY_NAME_W),
|
|
MAP(SCARD_ATTR_DEVICE_SYSTEM_NAME_W), MAP(SCARD_ATTR_SUPRESS_T1_IFS_REQUEST),
|
|
{ 0, NULL } };
|
|
|
|
static DWORD
|
|
l_dwPid = 0,
|
|
l_dwTid = 0;
|
|
|
|
|
|
/*++
|
|
|
|
main:
|
|
|
|
This is the main entry point for the program.
|
|
|
|
Arguments:
|
|
|
|
dwArgCount supplies the number of arguments.
|
|
|
|
szrgArgs supplies the argument strings.
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
Author:
|
|
|
|
Doug Barlow (dbarlow) 10/30/1997
|
|
|
|
--*/
|
|
|
|
void _cdecl
|
|
main(
|
|
IN DWORD dwArgCount,
|
|
IN LPCTSTR szrgArgs[])
|
|
{
|
|
LPCTSTR szInFile = NULL;
|
|
LPTSTR szEnd;
|
|
DWORD dwArgIndex = 0;
|
|
enum TraceAction {
|
|
Undefined = 0,
|
|
ClearLog,
|
|
ShowApiTrace,
|
|
ShowDriverTrace
|
|
} nTraceAction = Undefined;
|
|
|
|
|
|
//
|
|
// Check for command line options
|
|
//
|
|
|
|
while (NULL != szrgArgs[++dwArgIndex])
|
|
{
|
|
switch (SelectString(szrgArgs[dwArgIndex],
|
|
TEXT("CLEAR"), TEXT("RESET"),
|
|
TEXT("DRIVER"), TEXT("API"),
|
|
TEXT("-FILE"), TEXT("-PID"), TEXT("-TID"),
|
|
NULL))
|
|
{
|
|
case 1: // clear
|
|
case 2: // reset
|
|
if (Undefined != nTraceAction)
|
|
ShowSyntax(cerr);
|
|
nTraceAction = ClearLog;
|
|
break;
|
|
case 3: // driver
|
|
if (Undefined != nTraceAction)
|
|
ShowSyntax(cerr);
|
|
nTraceAction = ShowDriverTrace;
|
|
break;
|
|
case 4: // api
|
|
if (Undefined != nTraceAction)
|
|
ShowSyntax(cerr);
|
|
nTraceAction = ShowApiTrace;
|
|
break;
|
|
case 5: // -file
|
|
if (NULL != szInFile)
|
|
ShowSyntax(cerr);
|
|
szInFile = szrgArgs[++dwArgIndex];
|
|
if (NULL == szInFile)
|
|
ShowSyntax(cerr);
|
|
break;
|
|
case 6: // -pid <n>
|
|
if (0 != l_dwPid)
|
|
ShowSyntax(cerr);
|
|
dwArgIndex += 1;
|
|
l_dwPid = strtoul(szrgArgs[dwArgIndex], &szEnd, 0);
|
|
if ((0 == l_dwPid) || (0 != *szEnd))
|
|
ShowSyntax(cerr);
|
|
break;
|
|
case 7: // -tid <n>
|
|
if (0 != l_dwTid)
|
|
ShowSyntax(cerr);
|
|
dwArgIndex += 1;
|
|
l_dwTid = strtoul(szrgArgs[dwArgIndex], &szEnd, 0);
|
|
if ((0 == l_dwTid) || (0 != *szEnd))
|
|
ShowSyntax(cerr);
|
|
break;
|
|
default:
|
|
ShowSyntax(cerr);
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// Perform the request.
|
|
//
|
|
|
|
switch (nTraceAction)
|
|
{
|
|
case ClearLog:
|
|
{
|
|
HANDLE hLogFile;
|
|
|
|
if (NULL == szInFile)
|
|
{
|
|
hLogFile = CreateFile(
|
|
TEXT("C:\\Calais.log"),
|
|
GENERIC_WRITE,
|
|
0,
|
|
NULL,
|
|
TRUNCATE_EXISTING,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL);
|
|
if (INVALID_HANDLE_VALUE != hLogFile)
|
|
CloseHandle(hLogFile);
|
|
hLogFile = CreateFile(
|
|
TEXT("C:\\SCard.log"),
|
|
GENERIC_WRITE,
|
|
0,
|
|
NULL,
|
|
TRUNCATE_EXISTING,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL);
|
|
if (INVALID_HANDLE_VALUE != hLogFile)
|
|
CloseHandle(hLogFile);
|
|
}
|
|
else
|
|
{
|
|
hLogFile = CreateFile(
|
|
szInFile,
|
|
GENERIC_WRITE,
|
|
0,
|
|
NULL,
|
|
CREATE_ALWAYS,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL);
|
|
if (INVALID_HANDLE_VALUE == hLogFile)
|
|
{
|
|
DWORD dwError = GetLastError();
|
|
cerr << TEXT("Failed to initialize file ")
|
|
<< szInFile << TEXT(": ")
|
|
<< CErrorString(dwError) << endl;
|
|
}
|
|
else
|
|
CloseHandle(hLogFile);
|
|
}
|
|
break;
|
|
}
|
|
case Undefined:
|
|
case ShowApiTrace:
|
|
ShowApiLog(szInFile);
|
|
break;
|
|
case ShowDriverTrace:
|
|
ShowDriverLog(szInFile);
|
|
break;
|
|
default:
|
|
cerr << TEXT("Internal error") << endl;
|
|
}
|
|
|
|
exit(0);
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
ShowDriverLog:
|
|
|
|
Explain the contents of the driver log.
|
|
|
|
Arguments:
|
|
|
|
szFile supplies the name of the file to parse. If this is NULL, the file
|
|
C:\Calais.log is used.
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
Throws:
|
|
|
|
None
|
|
|
|
Author:
|
|
|
|
Doug Barlow (dbarlow) 8/5/1998
|
|
|
|
--*/
|
|
|
|
static void
|
|
ShowDriverLog(
|
|
IN LPCTSTR szFile)
|
|
{
|
|
static const ValueMap rgMapPower[]
|
|
= { MAP(SCARD_POWER_DOWN),
|
|
MAP(SCARD_COLD_RESET),
|
|
MAP(SCARD_WARM_RESET),
|
|
{ 0, NULL } };
|
|
HANDLE hLogFile = NULL;
|
|
DWORD cbStructLen = 0;
|
|
LPBYTE pbStruct = NULL;
|
|
LPCTSTR szInFile = TEXT("C:\\Calais.log");
|
|
DWORD dwLen, dwRead;
|
|
BOOL fSts;
|
|
RequestTrace *prqTrace;
|
|
LPBYTE pbInBuffer, pbOutBuffer;
|
|
LPDWORD pdwInValue, pdwOutValue;
|
|
|
|
|
|
//
|
|
// Open the log file.
|
|
//
|
|
|
|
if (NULL != szFile)
|
|
szInFile = szFile;
|
|
hLogFile = CreateFile(
|
|
szInFile,
|
|
GENERIC_READ,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL);
|
|
if (INVALID_HANDLE_VALUE == hLogFile)
|
|
{
|
|
cerr << TEXT("Can't open file ")
|
|
<< szInFile
|
|
<< ": "
|
|
<< ErrorString(GetLastError())
|
|
<< endl;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
|
|
//
|
|
// Parse the file contents.
|
|
//
|
|
|
|
for (;;)
|
|
{
|
|
fSts = ReadFile(
|
|
hLogFile,
|
|
&dwLen,
|
|
sizeof(DWORD),
|
|
&dwRead,
|
|
NULL);
|
|
if ((!fSts) || (0 == dwRead))
|
|
goto ErrorExit;
|
|
|
|
if (cbStructLen < dwLen)
|
|
{
|
|
if (NULL != pbStruct)
|
|
LocalFree(pbStruct);
|
|
pbStruct = (LPBYTE)LocalAlloc(LPTR, dwLen);
|
|
cbStructLen = dwLen;
|
|
}
|
|
prqTrace = (RequestTrace *)pbStruct;
|
|
prqTrace->dwStructLen = dwLen;
|
|
fSts = ReadFile(
|
|
hLogFile,
|
|
&pbStruct[sizeof(DWORD)],
|
|
dwLen - sizeof(DWORD),
|
|
&dwRead,
|
|
NULL);
|
|
if (!fSts)
|
|
{
|
|
cerr << "File read error: " << ErrorString(GetLastError()) << endl;
|
|
goto ErrorExit;
|
|
}
|
|
if ((l_dwPid != 0) && (l_dwPid != prqTrace->dwProcId))
|
|
continue;
|
|
if ((l_dwTid != 0) && (l_dwTid != prqTrace->dwThreadId))
|
|
continue;
|
|
|
|
|
|
//
|
|
// Parse the structure into bytesize chunks.
|
|
//
|
|
|
|
pbInBuffer = 0 != prqTrace->nInBufferSize
|
|
? (LPBYTE)prqTrace + prqTrace->nInBuffer
|
|
: NULL;
|
|
pbOutBuffer = 0 != prqTrace->nBytesReturned
|
|
? (LPBYTE)prqTrace + prqTrace->nOutBuffer
|
|
: NULL;
|
|
pdwInValue = sizeof(DWORD) <= prqTrace->nInBufferSize
|
|
? (LPDWORD)pbInBuffer
|
|
: NULL;
|
|
pdwOutValue = sizeof(DWORD) <= prqTrace->nBytesReturned
|
|
? (LPDWORD)pbOutBuffer
|
|
: NULL;
|
|
|
|
|
|
//
|
|
// We've got the structure, now display the contents.
|
|
//
|
|
|
|
cout
|
|
<< TEXT("-----------------------------------------------------\n")
|
|
<< TEXT("P/T: ") << PHex(prqTrace->dwProcId) << TEXT("/") << PHex(prqTrace->dwThreadId) << TCHAR('\n')
|
|
<< TEXT("Time: ") << PTime(prqTrace->StartTime) << TEXT(" - ") << PTime(prqTrace->EndTime) << TCHAR('\n')
|
|
<< TEXT("Device: ") << PHex((ULONG)prqTrace->hDevice) << TCHAR('\n')
|
|
<< TEXT("Status: ") << ErrorString(prqTrace->dwStatus) << TCHAR('\n')
|
|
<< TEXT("RecLen: ") << PDec(prqTrace->nOutBufferSize) << TCHAR('\n')
|
|
<< flush;
|
|
MapValue(cout, prqTrace->dwIoControlCode, TEXT("IOCTL: "), rgMapIoctl);
|
|
cout << flush;
|
|
switch (prqTrace->dwIoControlCode)
|
|
{
|
|
case IOCTL_SMARTCARD_POWER:
|
|
MapInput(cout, prqTrace, rgMapPower);
|
|
cout << flush;
|
|
MapOutput(cout, prqTrace, NULL);
|
|
break;
|
|
case IOCTL_SMARTCARD_GET_ATTRIBUTE:
|
|
MapInput(cout, prqTrace, rgMapAttr);
|
|
cout << flush;
|
|
MapOutput(cout, prqTrace, NULL);
|
|
break;
|
|
case IOCTL_SMARTCARD_SET_ATTRIBUTE:
|
|
{
|
|
GeneralDump(cout, prqTrace);
|
|
break;
|
|
}
|
|
case IOCTL_SMARTCARD_CONFISCATE:
|
|
GeneralDump(cout, prqTrace);
|
|
break;
|
|
case IOCTL_SMARTCARD_TRANSMIT:
|
|
{
|
|
LPCSCARD_IO_REQUEST pIo;
|
|
LPCBYTE pbPci, pbSdu;
|
|
DWORD cbPci, cbSdu;
|
|
|
|
if (sizeof(SCARD_IO_REQUEST) <= prqTrace->nInBufferSize)
|
|
{
|
|
pIo = (LPCSCARD_IO_REQUEST)pbInBuffer;
|
|
pbPci = pbInBuffer + sizeof(LPCSCARD_IO_REQUEST);
|
|
cbPci = min(pIo->cbPciLength, prqTrace->nInBufferSize);
|
|
pbSdu = pbInBuffer + pIo->cbPciLength;
|
|
cbSdu = prqTrace->nInBufferSize - cbPci;
|
|
cbPci -= sizeof(SCARD_IO_REQUEST);
|
|
|
|
MapValue(cout, pIo->dwProtocol, TEXT("Proto: "), rgMapProto);
|
|
if (0 < cbPci)
|
|
{
|
|
cout
|
|
<< TEXT("In PCI: (") << PDec(cbPci) << TEXT(" bytes)\n")
|
|
<< flush;
|
|
dump(pbPci, cbPci, cout);
|
|
}
|
|
cout
|
|
<< TEXT("Sent: (") << PDec(cbSdu) << TEXT(" bytes)\n")
|
|
<< flush;
|
|
dump(pbSdu, cbSdu, cout);
|
|
}
|
|
else
|
|
SendDump(cout, prqTrace);
|
|
if (sizeof(SCARD_IO_REQUEST) <= prqTrace->nBytesReturned)
|
|
{
|
|
pIo = (LPCSCARD_IO_REQUEST)pbOutBuffer;
|
|
pbPci = pbOutBuffer + sizeof(LPCSCARD_IO_REQUEST);
|
|
cbPci = min(pIo->cbPciLength, prqTrace->nBytesReturned);
|
|
pbSdu = pbOutBuffer + pIo->cbPciLength;
|
|
cbSdu = prqTrace->nBytesReturned - cbPci;
|
|
cbPci -= sizeof(SCARD_IO_REQUEST);
|
|
|
|
MapValue(cout, pIo->dwProtocol, TEXT("Proto: "), rgMapProto);
|
|
if (0 < cbPci)
|
|
{
|
|
cout
|
|
<< TEXT("Out PCI: (") << PDec(cbPci) << TEXT(" bytes)\n")
|
|
<< flush;
|
|
dump(pbPci, cbPci, cout);
|
|
}
|
|
cout
|
|
<< TEXT("Recd: (") << PDec(cbSdu) << TEXT(" bytes)\n")
|
|
<< flush;
|
|
dump(pbSdu, cbSdu, cout);
|
|
}
|
|
else
|
|
RecvDump(cout, prqTrace);
|
|
break;
|
|
}
|
|
case IOCTL_SMARTCARD_EJECT:
|
|
GeneralDump(cout, prqTrace);
|
|
break;
|
|
case IOCTL_SMARTCARD_SWALLOW:
|
|
GeneralDump(cout, prqTrace);
|
|
break;
|
|
case IOCTL_SMARTCARD_IS_PRESENT:
|
|
GeneralDump(cout, prqTrace);
|
|
break;
|
|
case IOCTL_SMARTCARD_IS_ABSENT:
|
|
GeneralDump(cout, prqTrace);
|
|
break;
|
|
case IOCTL_SMARTCARD_SET_PROTOCOL:
|
|
MapInput(cout, prqTrace, rgMapProto);
|
|
cout << flush;
|
|
MapOutput(cout, prqTrace, rgMapProto);
|
|
break;
|
|
case IOCTL_SMARTCARD_GET_STATE:
|
|
{
|
|
GeneralDump(cout, prqTrace);
|
|
break;
|
|
}
|
|
case IOCTL_SMARTCARD_GET_LAST_ERROR:
|
|
{
|
|
GeneralDump(cout, prqTrace);
|
|
break;
|
|
}
|
|
default:
|
|
GeneralDump(cout, prqTrace);
|
|
break;
|
|
}
|
|
cout << flush;
|
|
}
|
|
|
|
ErrorExit:
|
|
if (NULL == hLogFile)
|
|
CloseHandle(hLogFile);
|
|
}
|
|
|
|
|
|
static void
|
|
dump(
|
|
const BYTE *pbData,
|
|
DWORD cbLen,
|
|
ostream &outStr)
|
|
{
|
|
unsigned long int
|
|
b, i, lc;
|
|
char
|
|
buffer[8];
|
|
|
|
|
|
lc = 0;
|
|
while (0 < cbLen)
|
|
{
|
|
b = min(sizeof(buffer), cbLen);
|
|
memcpy(buffer, pbData, b);
|
|
pbData += b;
|
|
cbLen -= b;
|
|
if (0 < b)
|
|
{
|
|
outStr << TEXT(" ") << setw(8) << setfill(TEXT('0')) << hex << lc;
|
|
for (i = 0; i < b; i += 1)
|
|
outStr
|
|
<< " "
|
|
<< setw(2) << setfill('0') << hex
|
|
<< ((unsigned int)buffer[i] & 0xff);
|
|
for (; i < sizeof(buffer) + 1; i += 1)
|
|
outStr << " ";
|
|
for (i = 0; i < b; i += 1)
|
|
outStr
|
|
<< setw(0) << setfill(' ') << dec
|
|
<< ((0 != iscntrl((int)(0x7f & buffer[i])))
|
|
? TEXT('.')
|
|
: buffer[i]);
|
|
outStr << endl;
|
|
lc += b;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
GeneralDump(
|
|
ostream &outStr,
|
|
const RequestTrace *prqTrace)
|
|
{
|
|
SendDump(outStr, prqTrace);
|
|
outStr << flush;
|
|
RecvDump(outStr, prqTrace);
|
|
}
|
|
|
|
static void
|
|
SendDump(
|
|
ostream &outStr,
|
|
const RequestTrace *prqTrace)
|
|
{
|
|
outStr
|
|
<< TEXT("Sent: (") << PDec(prqTrace->nInBufferSize) << TEXT(" bytes)\n")
|
|
<< flush;
|
|
dump(
|
|
(LPBYTE)prqTrace + prqTrace->nInBuffer,
|
|
prqTrace->nInBufferSize,
|
|
outStr);
|
|
}
|
|
|
|
static void
|
|
RecvDump(
|
|
ostream &outStr,
|
|
const RequestTrace *prqTrace)
|
|
{
|
|
outStr
|
|
<< TEXT("Recd: (") << PDec(prqTrace->nBytesReturned) << TEXT(" bytes)\n")
|
|
<< flush;
|
|
dump(
|
|
(LPBYTE)prqTrace + prqTrace->nOutBuffer,
|
|
prqTrace->nBytesReturned,
|
|
outStr);
|
|
}
|
|
|
|
static void
|
|
MapValue(
|
|
ostream &outStr,
|
|
DWORD dwValue,
|
|
LPCTSTR szLeader,
|
|
const ValueMap *rgMap)
|
|
{
|
|
DWORD dwIndex;
|
|
|
|
if (NULL != rgMap)
|
|
{
|
|
for (dwIndex = 0; NULL != rgMap[dwIndex].szValue; dwIndex += 1)
|
|
if (rgMap[dwIndex].dwValue == dwValue)
|
|
break;
|
|
if (NULL != rgMap[dwIndex].szValue)
|
|
outStr << szLeader << rgMap[dwIndex].szValue << TEXT('\n');
|
|
else
|
|
outStr << szLeader << PHex(dwValue) << TEXT('\n');
|
|
}
|
|
else
|
|
outStr << szLeader << PHex(dwValue) << TEXT('\n');
|
|
}
|
|
|
|
static void
|
|
MaskValue(
|
|
ostream &outStr,
|
|
DWORD dwValue,
|
|
LPCTSTR szLeader,
|
|
const ValueMap *rgMap)
|
|
{
|
|
DWORD dwIndex;
|
|
BOOL fSpace = FALSE;
|
|
|
|
if (NULL != rgMap)
|
|
{
|
|
if (NULL != szLeader)
|
|
outStr << szLeader;
|
|
|
|
for (dwIndex = 0; NULL != rgMap[dwIndex].szValue; dwIndex += 1)
|
|
{
|
|
if (rgMap[dwIndex].dwValue == (rgMap[dwIndex].dwValue & dwValue))
|
|
{
|
|
if (fSpace)
|
|
outStr << TEXT(' ');
|
|
else
|
|
fSpace = TRUE;
|
|
outStr << rgMap[dwIndex].szValue;
|
|
dwValue &= ~rgMap[dwIndex].dwValue;
|
|
}
|
|
}
|
|
if (0 != dwValue)
|
|
{
|
|
if (fSpace)
|
|
{
|
|
outStr << TEXT(' ');
|
|
fSpace = TRUE;
|
|
}
|
|
outStr << PHex(dwValue);
|
|
}
|
|
else if (!fSpace)
|
|
outStr << PHex(dwValue);
|
|
outStr << endl;
|
|
}
|
|
else
|
|
outStr << szLeader << PHex(dwValue) << endl;
|
|
}
|
|
|
|
static void
|
|
MapInput(
|
|
ostream &outStr,
|
|
const RequestTrace *prqTrace,
|
|
const ValueMap *rgMap)
|
|
{
|
|
DWORD dwValue;
|
|
|
|
switch (prqTrace->nInBufferSize)
|
|
{
|
|
case 0:
|
|
break;
|
|
case sizeof(DWORD):
|
|
dwValue = *(LPDWORD)((LPBYTE)prqTrace + prqTrace->nInBuffer);
|
|
MapValue(outStr, dwValue, TEXT("Sent: "), rgMap);
|
|
break;
|
|
default:
|
|
SendDump(outStr, prqTrace);
|
|
}
|
|
}
|
|
|
|
static void
|
|
MapOutput(
|
|
ostream &outStr,
|
|
const RequestTrace *prqTrace,
|
|
const ValueMap *rgMap)
|
|
{
|
|
DWORD dwValue;
|
|
|
|
switch (prqTrace->nBytesReturned)
|
|
{
|
|
case 0:
|
|
break;
|
|
case sizeof(DWORD):
|
|
dwValue = *(LPDWORD)((LPBYTE)prqTrace + prqTrace->nOutBuffer);
|
|
MapValue(outStr, dwValue, TEXT("Recd: "), rgMap);
|
|
break;
|
|
default:
|
|
RecvDump(outStr, prqTrace);
|
|
}
|
|
}
|
|
|
|
/*++
|
|
|
|
ShowSyntax:
|
|
|
|
Display the command line usage model.
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
This routine calls exit(0), so it never returns.
|
|
|
|
Author:
|
|
|
|
Doug Barlow (dbarlow) 5/16/1998
|
|
|
|
--*/
|
|
|
|
static void
|
|
ShowSyntax(
|
|
ostream &outStr)
|
|
{
|
|
outStr << TEXT("Usage:\n")
|
|
<< TEXT("------------------------\n")
|
|
<< TEXT("clear [-file <logFile>]\n")
|
|
<< TEXT("api [-file <logFile>] [-pid <pid>] [-tid <tid>]\n")
|
|
<< TEXT("driver [-file <logFile>] [-pid <pid>] [-tid <tid>]\n")
|
|
<< TEXT("------------------------\n")
|
|
<< TEXT("DRIVER logs to C:\\Calais.log\n")
|
|
<< TEXT("API logs to C:\\SCard.log\n")
|
|
<< endl;
|
|
exit(1);
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
ShowApiLog:
|
|
|
|
Explain the contents of the API log.
|
|
|
|
Arguments:
|
|
|
|
szFile supplies the name of the file to parse. If this is NULL, the file
|
|
C:\SCard.log is used.
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
Throws:
|
|
|
|
None
|
|
|
|
Author:
|
|
|
|
Doug Barlow (dbarlow) 8/5/1998
|
|
|
|
--*/
|
|
|
|
static void
|
|
ShowApiLog(
|
|
IN LPCTSTR szFile)
|
|
{
|
|
static const ValueMap rgMapStates[]
|
|
= { MAP(SCARD_STATE_IGNORE),
|
|
MAP(SCARD_STATE_CHANGED),
|
|
MAP(SCARD_STATE_UNKNOWN),
|
|
MAP(SCARD_STATE_UNAVAILABLE),
|
|
MAP(SCARD_STATE_EMPTY),
|
|
MAP(SCARD_STATE_PRESENT),
|
|
MAP(SCARD_STATE_ATRMATCH),
|
|
MAP(SCARD_STATE_EXCLUSIVE),
|
|
MAP(SCARD_STATE_INUSE),
|
|
MAP(SCARD_STATE_MUTE),
|
|
MAP(SCARD_STATE_UNPOWERED),
|
|
{0, NULL} };
|
|
static const ValueMap rgMapDriverStates[]
|
|
= {
|
|
MAP(SCARD_UNKNOWN),
|
|
MAP(SCARD_ABSENT),
|
|
MAP(SCARD_PRESENT),
|
|
MAP(SCARD_SWALLOWED),
|
|
MAP(SCARD_POWERED),
|
|
MAP(SCARD_NEGOTIABLE),
|
|
MAP(SCARD_SPECIFIC),
|
|
{0, NULL} };
|
|
static const ValueMap rgMapShare[]
|
|
= {
|
|
MAP(SCARD_SHARE_EXCLUSIVE),
|
|
MAP(SCARD_SHARE_SHARED),
|
|
MAP(SCARD_SHARE_DIRECT),
|
|
{0, NULL} };
|
|
static const ValueMap rgMapDisposition[]
|
|
= { MAP(SCARD_LEAVE_CARD),
|
|
MAP(SCARD_RESET_CARD),
|
|
MAP(SCARD_UNPOWER_CARD),
|
|
MAP(SCARD_EJECT_CARD),
|
|
{0, NULL} };
|
|
HANDLE hLogFile = NULL;
|
|
LPCTSTR szInFile = TEXT("C:\\SCard.log");
|
|
CComObject *pCom = NULL;
|
|
DWORD dwLen;
|
|
|
|
|
|
//
|
|
// Open the log file.
|
|
//
|
|
|
|
if (NULL != szFile)
|
|
szInFile = szFile;
|
|
hLogFile = CreateFile(
|
|
szInFile,
|
|
GENERIC_READ,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
0,
|
|
NULL);
|
|
if (INVALID_HANDLE_VALUE == hLogFile)
|
|
{
|
|
cerr << TEXT("Can't open file ") << szInFile << ": "
|
|
<< ErrorString(GetLastError()) << endl;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
|
|
//
|
|
// Parse the file contents.
|
|
//
|
|
|
|
try
|
|
{
|
|
for (;;)
|
|
{
|
|
LogStamp stamp;
|
|
BOOL fSts;
|
|
|
|
fSts = ReadFile(
|
|
hLogFile,
|
|
&stamp,
|
|
sizeof(stamp),
|
|
&dwLen,
|
|
NULL);
|
|
ASSERT(fSts);
|
|
pCom = ReceiveComObject(hLogFile);
|
|
if (NULL == pCom)
|
|
break;
|
|
if ((l_dwPid != 0) && (l_dwPid != stamp.dwProcId))
|
|
continue;
|
|
if ((l_dwTid != 0) && (l_dwTid != stamp.dwProcId))
|
|
continue;
|
|
cout
|
|
<< TEXT("------------------------------------------------------------\n")
|
|
<< TEXT("Process/Thread: ") << PHex(stamp.dwProcId) << TEXT("/") << PHex(stamp.dwThreadId) << TEXT("\n")
|
|
<< TEXT("Time: ") << PTime(stamp.stLogTime) << endl;
|
|
switch (pCom->Type())
|
|
{
|
|
case CComObject::EstablishContext_request:
|
|
{
|
|
ComEstablishContext::CObjEstablishContext_request *pReq
|
|
= (ComEstablishContext::CObjEstablishContext_request *)pCom->Request();
|
|
cout
|
|
<< TEXT("Establish Context request\n")
|
|
<< TEXT("Requesting Process: ") << PHex(pReq->dwProcId) << TEXT("\n")
|
|
<< flush;
|
|
break;
|
|
}
|
|
|
|
case CComObject::ReleaseContext_request:
|
|
{
|
|
ComReleaseContext::CObjReleaseContext_request *pReq =
|
|
(ComReleaseContext::CObjReleaseContext_request *)pCom->Request();
|
|
cout
|
|
<< TEXT("Release Context request\n")
|
|
<< flush;
|
|
break;
|
|
}
|
|
|
|
case CComObject::IsValidContext_request:
|
|
{
|
|
ComIsValidContext::CObjIsValidContext_request *pReq =
|
|
(ComIsValidContext::CObjIsValidContext_request *)pCom->Request();
|
|
cout
|
|
<< TEXT("Is Valid Context request\n")
|
|
<< flush;
|
|
break;
|
|
}
|
|
|
|
case CComObject::LocateCards_request:
|
|
{
|
|
DWORD cbTotAtrs, cbTotMasks, dwStateCount, dwIndex;
|
|
LPCTSTR szReader;
|
|
ComLocateCards::CObjLocateCards_request *pReq =
|
|
(ComLocateCards::CObjLocateCards_request *)pCom->Request();
|
|
LPCBYTE pbAtrs = (LPCBYTE)pCom->Parse(pReq->dscAtrs, &cbTotAtrs);
|
|
LPCBYTE pbMasks = (LPCBYTE)pCom->Parse(pReq->dscAtrMasks, &cbTotMasks);
|
|
LPCTSTR mszReaders = (LPCTSTR)pCom->Parse(pReq->dscReaders);
|
|
LPDWORD rgdwStates = (LPDWORD)pCom->Parse(pReq->dscReaderStates, &dwStateCount);
|
|
cout
|
|
<< TEXT("Locate Cards request\n")
|
|
<< flush;
|
|
if (0 == cbTotAtrs)
|
|
{
|
|
cout << TEXT("ERROR -- Invalid ATR array") << endl;
|
|
continue;
|
|
}
|
|
else if (0 == cbTotMasks)
|
|
{
|
|
cout << TEXT("ERROR -- Invalid Mask array") << endl;
|
|
continue;
|
|
}
|
|
else if (0 == dwStateCount)
|
|
{
|
|
cout << TEXT("ERROR -- Invalid State array") << endl;
|
|
continue;
|
|
}
|
|
else if (0 != dwStateCount % sizeof(DWORD))
|
|
{
|
|
cout << TEXT("ERROR -- Invalid State array length") << endl;
|
|
continue;
|
|
}
|
|
else if (0 == *mszReaders)
|
|
{
|
|
cout << TEXT("ERROR -- Invalid Reader Name String") << endl;
|
|
continue;
|
|
}
|
|
dwStateCount /= sizeof(DWORD);
|
|
cout
|
|
<< TEXT("Looking for ATRs:\n")
|
|
<< flush;
|
|
while (0 < cbTotAtrs)
|
|
{
|
|
DWORD cbLength;
|
|
|
|
cbLength = *pbAtrs++;
|
|
cout << TEXT("ATR:\n") << flush;
|
|
dump(pbAtrs, cbLength, cout);
|
|
pbAtrs += cbLength;
|
|
cbTotAtrs -= cbLength + 1;
|
|
cbLength = *pbMasks++;
|
|
cout << TEXT("Mask:\n") << flush;
|
|
dump(pbMasks, cbLength, cout);
|
|
pbMasks += cbLength;
|
|
}
|
|
cout
|
|
<< TEXT("Looking in readers:\n")
|
|
<< flush;
|
|
for (dwIndex = 0, szReader = FirstString(mszReaders);
|
|
dwIndex < dwStateCount;
|
|
dwIndex += 1, szReader = NextString(szReader))
|
|
{
|
|
cout
|
|
<< TEXT(" ") << szReader << TEXT(":\n")
|
|
<< TEXT(" ")
|
|
<< flush;
|
|
if (0 == rgdwStates[dwIndex])
|
|
cout << TEXT("SCARD_STATE_UNAWARE\n") << flush;
|
|
else
|
|
MaskValue(cout, rgdwStates[dwIndex], NULL, rgMapStates);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case CComObject::GetStatusChange_request:
|
|
{
|
|
DWORD dwIndex;
|
|
LPCTSTR szReader;
|
|
ComGetStatusChange::CObjGetStatusChange_request *pReq =
|
|
(ComGetStatusChange::CObjGetStatusChange_request *)pCom->Request();
|
|
LPCTSTR mszReaders = (LPCTSTR)pCom->Parse(pReq->dscReaders);
|
|
LPDWORD rgdwStates = (LPDWORD)pCom->Parse(pReq->dscReaderStates, &dwLen);
|
|
cout
|
|
<< TEXT("Get Status Change request\n")
|
|
<< flush;
|
|
if (0 == dwLen)
|
|
{
|
|
cout << TEXT("ERROR -- Invalid State array") << endl;
|
|
continue;
|
|
}
|
|
else if (0 != dwLen % sizeof(DWORD))
|
|
{
|
|
cout << TEXT("ERROR -- Invalid State array length") << endl;
|
|
continue;
|
|
}
|
|
else if (0 == *mszReaders)
|
|
{
|
|
cout << TEXT("ERROR -- Invalid Reader Name String") << endl;
|
|
continue;
|
|
}
|
|
cout
|
|
<< TEXT("Timeout: ") << PDec(pReq->dwTimeout) << TEXT(" Milliseconds\n")
|
|
<< TEXT("Monitoring readers:\n")
|
|
<< flush;
|
|
for (dwIndex = 0, szReader = FirstString(mszReaders);
|
|
NULL != szReader;
|
|
dwIndex += 1, szReader = NextString(szReader))
|
|
{
|
|
cout
|
|
<< TEXT(" ") << szReader << TEXT(":\n")
|
|
<< flush;
|
|
if (0 == rgdwStates[dwIndex])
|
|
cout << TEXT(" SCARD_STATE_UNAWARE") << endl;
|
|
else
|
|
MaskValue(cout, rgdwStates[dwIndex], TEXT(" "), rgMapStates);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case CComObject::ListReaders_request:
|
|
{
|
|
LPCTSTR szReader;
|
|
ComListReaders::CObjListReaders_request *pReq =
|
|
(ComListReaders::CObjListReaders_request *)pCom->Request();
|
|
LPCTSTR mszQueryReaders = (LPCTSTR)pCom->Parse(pReq->dscReaders);
|
|
cout
|
|
<< TEXT("List Readers request\n")
|
|
<< TEXT("Readers:\n")
|
|
<< flush;
|
|
for (szReader = FirstString(mszQueryReaders);
|
|
NULL != szReader;
|
|
szReader = NextString(szReader))
|
|
{
|
|
cout << TEXT(" ") << szReader << endl;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case CComObject::Connect_request:
|
|
{
|
|
ComConnect::CObjConnect_request *pReq
|
|
= (ComConnect::CObjConnect_request *)pCom->Request();
|
|
LPCTSTR szReader = (LPCTSTR)pCom->Parse(pReq->dscReader);
|
|
cout
|
|
<< TEXT("Connect request\n")
|
|
<< TEXT("Reader: ") << szReader << endl;
|
|
MapValue(cout, pReq->dwPreferredProtocols,
|
|
TEXT("Protocols: "), rgMapProto);
|
|
MapValue(cout, pReq->dwShareMode,
|
|
TEXT("Sharing Mode: "), rgMapShare);
|
|
break;
|
|
}
|
|
|
|
case CComObject::Reconnect_request:
|
|
{
|
|
ComReconnect::CObjReconnect_request *pReq
|
|
= (ComReconnect::CObjReconnect_request *)pCom->Request();
|
|
cout
|
|
<< TEXT("Reconnect request\n")
|
|
<< TEXT("Handle: ") << PHex(pReq->hCard) << TEXT("\n")
|
|
<< flush;
|
|
MapValue(cout, pReq->dwInitialization,
|
|
TEXT("Disposition: "), rgMapDisposition);
|
|
MapValue(cout, pReq->dwPreferredProtocols,
|
|
TEXT("Protocols: "), rgMapProto);
|
|
MapValue(cout, pReq->dwShareMode,
|
|
TEXT("Sharing Mode: "), rgMapShare);
|
|
break;
|
|
}
|
|
|
|
case CComObject::Disconnect_request:
|
|
{
|
|
ComDisconnect::CObjDisconnect_request *pReq
|
|
= (ComDisconnect::CObjDisconnect_request *)pCom->Request();
|
|
cout
|
|
<< TEXT("Disconnect request\n")
|
|
<< TEXT("Handle: ") << PHex(pReq->hCard) << TEXT("\n")
|
|
<< flush;
|
|
MapValue(cout, pReq->dwDisposition,
|
|
TEXT("Disposition: "), rgMapDisposition);
|
|
break;
|
|
}
|
|
|
|
case CComObject::BeginTransaction_request:
|
|
{
|
|
ComBeginTransaction::CObjBeginTransaction_request *pReq
|
|
= (ComBeginTransaction::CObjBeginTransaction_request *)
|
|
pCom->Request();
|
|
cout
|
|
<< TEXT("Begin Transaction request\n")
|
|
<< TEXT("Handle: ") << PHex(pReq->hCard) << TEXT("\n")
|
|
<< flush;
|
|
break;
|
|
}
|
|
|
|
case CComObject::EndTransaction_request:
|
|
{
|
|
ComEndTransaction::CObjEndTransaction_request *pReq
|
|
= (ComEndTransaction::CObjEndTransaction_request *)pCom->Request();
|
|
cout
|
|
<< TEXT("End Transaction request\n")
|
|
<< TEXT("Handle: ") << PHex(pReq->hCard) << TEXT("\n")
|
|
<< flush;
|
|
MapValue(cout, pReq->dwDisposition,
|
|
TEXT("Disposition: "), rgMapDisposition);
|
|
break;
|
|
}
|
|
|
|
case CComObject::Status_request:
|
|
{
|
|
ComStatus::CObjStatus_request *pReq
|
|
= (ComStatus::CObjStatus_request *)pCom->Request();
|
|
cout
|
|
<< TEXT("Status request\n")
|
|
<< TEXT("Handle: ") << PHex(pReq->hCard) << TEXT("\n")
|
|
<< flush;
|
|
break;
|
|
}
|
|
|
|
case CComObject::Transmit_request:
|
|
{
|
|
DWORD cbPci, cbData;
|
|
ComTransmit::CObjTransmit_request *pReq
|
|
= (ComTransmit::CObjTransmit_request *)pCom->Request();
|
|
SCARD_IO_REQUEST *pioReq = (SCARD_IO_REQUEST *)pCom->Parse(pReq->dscSendPci, &cbPci);
|
|
LPCBYTE pbSendData = (LPCBYTE)pCom->Parse(pReq->dscSendBuffer, &cbData);
|
|
cout
|
|
<< TEXT("Transmit request\n")
|
|
<< TEXT("Handle: ") << PHex(pReq->hCard) << TEXT("\n")
|
|
<< TEXT("PCI:\n")
|
|
<< flush;
|
|
dump((LPCBYTE)pioReq, cbPci, cout);
|
|
cout
|
|
<< TEXT("Data:\n")
|
|
<< flush;
|
|
dump(pbSendData, cbData, cout);
|
|
cout
|
|
<< TEXT("Return PCI Length: ") << PDec(pReq->dwPciLength) << TEXT("\n")
|
|
<< TEXT("Return Data Length: ") << PDec(pReq->dwRecvLength) << TEXT("\n")
|
|
<< flush;
|
|
break;
|
|
}
|
|
|
|
case CComObject::Control_request:
|
|
{
|
|
ComControl::CObjControl_request *pReq
|
|
= (ComControl::CObjControl_request *)pCom->Request();
|
|
LPCBYTE pbInData = (LPCBYTE)pCom->Parse(pReq->dscInBuffer, &dwLen);
|
|
cout
|
|
<< TEXT("Control request\n")
|
|
<< TEXT("Handle: ") << PHex(pReq->hCard) << TEXT("\n")
|
|
<< flush;
|
|
MapValue(cout, pReq->dwControlCode,
|
|
TEXT("Control Code: "), rgMapIoctl);
|
|
cout << TEXT("Control Data:\n") << flush;
|
|
dump(pbInData, dwLen, cout);
|
|
cout
|
|
<< TEXT("Return Data Length: ") << PDec(pReq->dwOutLength) << TEXT("\n")
|
|
<< flush;
|
|
break;
|
|
}
|
|
|
|
case CComObject::GetAttrib_request:
|
|
{
|
|
ComGetAttrib::CObjGetAttrib_request *pReq
|
|
= (ComGetAttrib::CObjGetAttrib_request *)pCom->Request();
|
|
cout
|
|
<< TEXT("Get Attribute request\n")
|
|
<< TEXT("Handle: ") << PHex(pReq->hCard) << TEXT("\n")
|
|
<< flush;
|
|
MapValue(cout, pReq->dwAttrId,
|
|
TEXT("Attribute: "), rgMapAttr);
|
|
cout
|
|
<< TEXT("Return Data Length: ") << PDec(pReq->dwOutLength) << TEXT("\n")
|
|
<< flush;
|
|
break;
|
|
}
|
|
|
|
case CComObject::SetAttrib_request:
|
|
{
|
|
ComSetAttrib::CObjSetAttrib_request *pReq
|
|
= (ComSetAttrib::CObjSetAttrib_request *)pCom->Request();
|
|
LPCBYTE pbAttr = (LPCBYTE)pCom->Parse(pReq->dscAttr, &dwLen);
|
|
cout
|
|
<< TEXT("Set Attribute request\n")
|
|
<< TEXT("Handle: ") << PHex(pReq->hCard) << TEXT("\n")
|
|
<< flush;
|
|
MapValue(cout, pReq->dwAttrId,
|
|
TEXT("Attribute: "), rgMapAttr);
|
|
cout << TEXT("Data:") << endl;
|
|
dump(pbAttr, dwLen, cout);
|
|
break;
|
|
}
|
|
|
|
case CComObject::EstablishContext_response:
|
|
{
|
|
ComEstablishContext::CObjEstablishContext_response *pRsp
|
|
= (ComEstablishContext::CObjEstablishContext_response *)pCom->Response();
|
|
cout
|
|
<< TEXT("Establish Context response\n")
|
|
<< TEXT("Status: ") << ErrorString(pRsp->dwStatus) << TEXT("\n")
|
|
<< flush;
|
|
if (SCARD_S_SUCCESS == pRsp->dwStatus)
|
|
{
|
|
LPCTSTR szCancelEvent = (LPCTSTR)pCom->Parse(pRsp->dscCancelEvent);
|
|
cout
|
|
<< TEXT("Alt Event Name: ") << szCancelEvent << TEXT("\n")
|
|
<< flush;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case CComObject::ReleaseContext_response:
|
|
{
|
|
ComReleaseContext::CObjReleaseContext_response *pRsp =
|
|
(ComReleaseContext::CObjReleaseContext_response *)pCom->Response();
|
|
cout
|
|
<< TEXT("Release Context response\n")
|
|
<< TEXT("Status: ") << ErrorString(pRsp->dwStatus) << TEXT("\n")
|
|
<< flush;
|
|
break;
|
|
}
|
|
|
|
case CComObject::IsValidContext_response:
|
|
{
|
|
ComIsValidContext::CObjIsValidContext_response *pRsp =
|
|
(ComIsValidContext::CObjIsValidContext_response *)pCom->Response();
|
|
cout
|
|
<< TEXT("Is Valid Context response\n")
|
|
<< TEXT("Status: ") << ErrorString(pRsp->dwStatus) << TEXT("\n")
|
|
<< flush;
|
|
break;
|
|
}
|
|
|
|
case CComObject::LocateCards_response:
|
|
{
|
|
DWORD dwIndex, dwAtrLen;
|
|
ComLocateCards::CObjLocateCards_response *pRsp =
|
|
(ComLocateCards::CObjLocateCards_response *)pCom->Response();
|
|
cout
|
|
<< TEXT("Locate Cards response\n")
|
|
<< TEXT("Status: ") << ErrorString(pRsp->dwStatus) << TEXT("\n")
|
|
<< flush;
|
|
if (SCARD_S_SUCCESS == pRsp->dwStatus)
|
|
{
|
|
LPDWORD rgdwStates = (LPDWORD)pCom->Parse(pRsp->dscReaderStates, &dwLen);
|
|
LPCBYTE pbAtrs = (LPCBYTE)pCom->Parse(pRsp->dscAtrs);
|
|
|
|
dwLen /= sizeof(DWORD);
|
|
for (dwIndex = 0; dwIndex < dwLen; dwIndex += 1)
|
|
{
|
|
cout << TEXT("Mask:\n ") << flush;
|
|
if (0 == rgdwStates[dwIndex])
|
|
cout << TEXT("SCARD_STATE_UNAWARE") << endl;
|
|
MaskValue(cout, rgdwStates[dwIndex], NULL, rgMapStates);
|
|
cout << TEXT("ATR:\n") << flush;
|
|
dwAtrLen = *pbAtrs++;
|
|
dump(pbAtrs, dwAtrLen, cout);
|
|
pbAtrs += dwAtrLen;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
case CComObject::GetStatusChange_response:
|
|
{
|
|
DWORD dwIndex, dwAtrLen;
|
|
ComGetStatusChange::CObjGetStatusChange_response *pRsp =
|
|
(ComGetStatusChange::CObjGetStatusChange_response *)pCom->Response();
|
|
cout
|
|
<< TEXT("Get Status Change response\n")
|
|
<< TEXT("Status: ") << ErrorString(pRsp->dwStatus) << TEXT("\n")
|
|
<< flush;
|
|
if (SCARD_S_SUCCESS == pRsp->dwStatus)
|
|
{
|
|
LPDWORD rgdwStates = (LPDWORD)pCom->Parse(pRsp->dscReaderStates, &dwLen);
|
|
LPCBYTE pbAtrs = (LPCBYTE)pCom->Parse(pRsp->dscAtrs);
|
|
|
|
dwLen /= sizeof(DWORD);
|
|
for (dwIndex = 0; dwIndex < dwLen; dwIndex += 1)
|
|
{
|
|
cout << TEXT("Mask:\n") << flush;
|
|
if (0 == rgdwStates[dwIndex])
|
|
cout << TEXT(" SCARD_STATE_UNAWARE") << endl;
|
|
else
|
|
MaskValue(cout, rgdwStates[dwIndex], TEXT(" "), rgMapStates);
|
|
cout << TEXT("ATR:\n") << flush;
|
|
dwAtrLen = *pbAtrs++;
|
|
dump(pbAtrs, dwAtrLen, cout);
|
|
pbAtrs += dwAtrLen;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
case CComObject::ListReaders_response:
|
|
{
|
|
DWORD dwIndex;
|
|
|
|
ComListReaders::CObjListReaders_response *pRsp =
|
|
(ComListReaders::CObjListReaders_response *)pCom->Response();
|
|
cout
|
|
<< TEXT("List Readers response\n")
|
|
<< TEXT("Status: ") << ErrorString(pRsp->dwStatus) << TEXT("\n")
|
|
<< flush;
|
|
if (SCARD_S_SUCCESS == pRsp->dwStatus)
|
|
{
|
|
LPDWORD pdwReaders = (LPDWORD)pCom->Parse(pRsp->dscReaders, &dwLen);
|
|
cout
|
|
<< TEXT("Readers:\n")
|
|
<< flush;
|
|
dwLen /= sizeof(DWORD);
|
|
for (dwIndex = 0; dwIndex < dwLen; dwIndex += 1)
|
|
{
|
|
if (0 != pdwReaders[dwIndex])
|
|
cout << TEXT(" Present") << endl;
|
|
else
|
|
cout << TEXT(" Offline") << endl;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
case CComObject::Connect_response:
|
|
{
|
|
ComConnect::CObjConnect_response *pRsp
|
|
= (ComConnect::CObjConnect_response *)pCom->Response();
|
|
cout
|
|
<< TEXT("Connect response\n")
|
|
<< TEXT("Status: ") << ErrorString(pRsp->dwStatus) << TEXT("\n")
|
|
<< flush;
|
|
if (SCARD_S_SUCCESS == pRsp->dwStatus)
|
|
{
|
|
cout
|
|
<< TEXT("SCARDHANDLE: ") << PHex(pRsp->hCard) << TEXT("\n")
|
|
<< flush;
|
|
MapValue(cout, pRsp->dwActiveProtocol,
|
|
TEXT("Protocol: "), rgMapProto);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case CComObject::Reconnect_response:
|
|
{
|
|
ComReconnect::CObjReconnect_response *pRsp
|
|
= (ComReconnect::CObjReconnect_response *)pCom->Response();
|
|
cout
|
|
<< TEXT("Reconnect response\n")
|
|
<< TEXT("Status: ") << ErrorString(pRsp->dwStatus) << TEXT("\n")
|
|
<< flush;
|
|
if (SCARD_S_SUCCESS == pRsp->dwStatus)
|
|
{
|
|
MapValue(cout, pRsp->dwActiveProtocol,
|
|
TEXT("Protocol: "), rgMapProto);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case CComObject::Disconnect_response:
|
|
{
|
|
ComDisconnect::CObjDisconnect_response *pRsp
|
|
= (ComDisconnect::CObjDisconnect_response *)pCom->Response();
|
|
cout
|
|
<< TEXT("Disconnect response\n")
|
|
<< TEXT("Status: ") << ErrorString(pRsp->dwStatus) << TEXT("\n")
|
|
<< flush;
|
|
break;
|
|
}
|
|
|
|
case CComObject::BeginTransaction_response:
|
|
{
|
|
ComBeginTransaction::CObjBeginTransaction_response *pRsp
|
|
= (ComBeginTransaction::CObjBeginTransaction_response *)
|
|
pCom->Response();
|
|
cout
|
|
<< TEXT("Begin Transaction response\n")
|
|
<< TEXT("Status: ") << ErrorString(pRsp->dwStatus) << TEXT("\n")
|
|
<< flush;
|
|
break;
|
|
}
|
|
|
|
case CComObject::EndTransaction_response:
|
|
{
|
|
ComEndTransaction::CObjEndTransaction_response *pRsp
|
|
= (ComEndTransaction::CObjEndTransaction_response *)pCom->Response();
|
|
cout
|
|
<< TEXT("End Transaction response\n")
|
|
<< TEXT("Status: ") << ErrorString(pRsp->dwStatus) << TEXT("\n")
|
|
<< flush;
|
|
break;
|
|
}
|
|
|
|
case CComObject::Status_response:
|
|
{
|
|
DWORD cbAtrLen;
|
|
ComStatus::CObjStatus_response *pRsp
|
|
= (ComStatus::CObjStatus_response *)pCom->Response();
|
|
cout
|
|
<< TEXT("Status response\n")
|
|
<< TEXT("Status: ") << ErrorString(pRsp->dwStatus) << TEXT("\n")
|
|
<< flush;
|
|
if (SCARD_S_SUCCESS == pRsp->dwStatus)
|
|
{
|
|
LPCBYTE pbAtr = (LPCBYTE)pCom->Parse(pRsp->dscAtr, &cbAtrLen);
|
|
LPCTSTR szRdr = (LPCTSTR)pCom->Parse(pRsp->dscSysName);
|
|
|
|
MapValue(cout, pRsp->dwState,
|
|
TEXT("State: "), rgMapDriverStates);
|
|
MapValue(cout, pRsp->dwProtocol,
|
|
TEXT("Protocol: "), rgMapProto);
|
|
cout
|
|
<< TEXT("ATR:\n")
|
|
<< flush;
|
|
dump(pbAtr, cbAtrLen, cout);
|
|
cout
|
|
<< TEXT("Reader Sys Name: ") << szRdr << endl;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case CComObject::Transmit_response:
|
|
{
|
|
DWORD cbPci, cbData;
|
|
ComTransmit::CObjTransmit_response *pRsp
|
|
= (ComTransmit::CObjTransmit_response *)pCom->Response();
|
|
cout
|
|
<< TEXT("Transmit response\n")
|
|
<< TEXT("Status: ") << ErrorString(pRsp->dwStatus) << TEXT("\n")
|
|
<< flush;
|
|
if (SCARD_S_SUCCESS == pRsp->dwStatus)
|
|
{
|
|
SCARD_IO_REQUEST *pioRsp = (SCARD_IO_REQUEST *)pCom->Parse(pRsp->dscRecvPci, &cbPci);
|
|
LPCBYTE pbRecvData = (LPCBYTE)pCom->Parse(pRsp->dscRecvBuffer, &cbData);
|
|
cout
|
|
<< TEXT("PCI:\n")
|
|
<< flush;
|
|
dump((LPCBYTE)pioRsp, cbPci, cout);
|
|
cout
|
|
<< TEXT("Data:\n")
|
|
<< flush;
|
|
dump(pbRecvData, cbData, cout);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case CComObject::Control_response:
|
|
{
|
|
ComControl::CObjControl_response *pRsp
|
|
= (ComControl::CObjControl_response *)pCom->Response();
|
|
LPCBYTE pbData = (LPCBYTE)pCom->Parse(pRsp->dscOutBuffer, &dwLen);
|
|
cout
|
|
<< TEXT("Control response\n")
|
|
<< TEXT("Status: ") << ErrorString(pRsp->dwStatus) << TEXT("\n")
|
|
<< flush;
|
|
if (SCARD_S_SUCCESS == pRsp->dwStatus)
|
|
{
|
|
LPCBYTE pbData = (LPCBYTE)pCom->Parse(pRsp->dscOutBuffer, &dwLen);
|
|
cout
|
|
<< TEXT("Data:\n")
|
|
<< flush;
|
|
dump(pbData, dwLen, cout);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case CComObject::GetAttrib_response:
|
|
{
|
|
ComGetAttrib::CObjGetAttrib_response *pRsp
|
|
= (ComGetAttrib::CObjGetAttrib_response *)pCom->Response();
|
|
cout
|
|
<< TEXT("Get Attribute response\n")
|
|
<< TEXT("Status: ") << ErrorString(pRsp->dwStatus) << TEXT("\n")
|
|
<< flush;
|
|
if (SCARD_S_SUCCESS == pRsp->dwStatus)
|
|
{
|
|
LPCBYTE pbData = (LPCBYTE)pCom->Parse(pRsp->dscAttr, &dwLen);
|
|
cout
|
|
<< TEXT("Data:\n")
|
|
<< flush;
|
|
dump(pbData, dwLen, cout);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case CComObject::SetAttrib_response:
|
|
{
|
|
ComSetAttrib::CObjSetAttrib_response *pRsp
|
|
= (ComSetAttrib::CObjSetAttrib_response *)pCom->Response();
|
|
cout
|
|
<< TEXT("Set Attribute response\n")
|
|
<< TEXT("Status: ") << ErrorString(pRsp->dwStatus) << TEXT("\n")
|
|
<< flush;
|
|
break;
|
|
}
|
|
|
|
default:
|
|
if (0 == (1 & pCom->Type()))
|
|
{
|
|
CComObject::CObjGeneric_request *pReq
|
|
= (CComObject::CObjGeneric_request *)pCom->Request();
|
|
cout
|
|
<< TEXT("Unrecognized request\n")
|
|
<< flush;
|
|
}
|
|
else
|
|
{
|
|
CComObject::CObjGeneric_response *pRsp
|
|
= (CComObject::CObjGeneric_response *)pCom->Response();
|
|
cout
|
|
<< TEXT("Unrecognized response\n")
|
|
<< TEXT("Status: ") << ErrorString(pRsp->dwStatus) << TEXT("\n")
|
|
<< flush;
|
|
}
|
|
}
|
|
|
|
delete pCom;
|
|
pCom = NULL;
|
|
}
|
|
}
|
|
catch (...)
|
|
{
|
|
if (NULL != pCom)
|
|
delete pCom;
|
|
cerr << TEXT("\n*** ERROR *** Exception parsing log file") << endl;
|
|
}
|
|
|
|
ErrorExit:
|
|
if (NULL != hLogFile)
|
|
CloseHandle(hLogFile);
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
ReceiveComObject:
|
|
|
|
This routine creates the proper CComObject child object for the data
|
|
coming in from a log file.
|
|
|
|
Arguments:
|
|
|
|
hFile supplies the file handle from which the data is to be extracted.
|
|
|
|
Return Value:
|
|
|
|
The newly created CComObject child object. This object must be cleaned up
|
|
via the delete command.
|
|
|
|
Throws:
|
|
|
|
?exceptions?
|
|
|
|
Author:
|
|
|
|
Doug Barlow (dbarlow) 11/13/1996
|
|
|
|
--*/
|
|
|
|
CComObject *
|
|
ReceiveComObject(
|
|
HANDLE hFile)
|
|
{
|
|
CComObject *pCom = NULL;
|
|
|
|
try
|
|
{
|
|
DWORD rgdwInData[2];
|
|
DWORD dwLen;
|
|
BOOL fSts;
|
|
|
|
|
|
//
|
|
// See what's coming.
|
|
//
|
|
|
|
fSts = ReadFile(
|
|
hFile,
|
|
rgdwInData,
|
|
sizeof(rgdwInData),
|
|
&dwLen,
|
|
NULL);
|
|
if (!fSts)
|
|
{
|
|
DWORD dwSts = GetLastError();
|
|
switch (dwSts)
|
|
{
|
|
case ERROR_HANDLE_EOF:
|
|
throw dwSts;
|
|
break;
|
|
default:
|
|
cerr << TEXT("Can't read input file: ")
|
|
<< ErrorString(dwSts);
|
|
throw dwSts;
|
|
}
|
|
}
|
|
else if (0 == dwLen)
|
|
throw (DWORD)ERROR_HANDLE_EOF;
|
|
else if (dwLen != sizeof(rgdwInData))
|
|
throw (DWORD)SCARD_F_COMM_ERROR;
|
|
|
|
switch (rgdwInData[0]) // dwCommndId
|
|
{
|
|
case CComObject::EstablishContext_request:
|
|
pCom = new ComEstablishContext;
|
|
break;
|
|
case CComObject::EstablishContext_response:
|
|
pCom = new ComEstablishContext;
|
|
break;
|
|
case CComObject::ReleaseContext_request:
|
|
pCom = new ComReleaseContext;
|
|
break;
|
|
case CComObject::ReleaseContext_response:
|
|
pCom = new ComReleaseContext;
|
|
break;
|
|
case CComObject::IsValidContext_request:
|
|
pCom = new ComIsValidContext;
|
|
break;
|
|
case CComObject::IsValidContext_response:
|
|
pCom = new ComIsValidContext;
|
|
break;
|
|
case CComObject::ListReaders_request:
|
|
pCom = new ComListReaders;
|
|
break;
|
|
case CComObject::ListReaders_response:
|
|
pCom = new ComListReaders;
|
|
break;
|
|
#if 0
|
|
case CComObject::ListReaderGroups_request:
|
|
pCom = new ComListReaderGroups;
|
|
break;
|
|
case CComObject::ListReaderGroups_response:
|
|
pCom = new ComListReaderGroups;
|
|
break;
|
|
case CComObject::ListCards_request:
|
|
pCom = new ComListCards;
|
|
break;
|
|
case CComObject::ListCards_response:
|
|
pCom = new ComListCards;
|
|
break;
|
|
case CComObject::ListInterfaces_request:
|
|
pCom = new ComListInterfaces;
|
|
break;
|
|
case CComObject::ListInterfaces_response:
|
|
pCom = new ComListInterfaces;
|
|
break;
|
|
case CComObject::GetProviderId_request:
|
|
pCom = new ComGetProviderId;
|
|
break;
|
|
case CComObject::GetProviderId_response:
|
|
pCom = new ComGetProviderId;
|
|
break;
|
|
case CComObject::IntroduceReaderGroup_request:
|
|
pCom = new ComIntroduceReaderGroup;
|
|
break;
|
|
case CComObject::IntroduceReaderGroup_response:
|
|
pCom = new ComIntroduceReaderGroup;
|
|
break;
|
|
case CComObject::ForgetReaderGroup_request:
|
|
pCom = new ComForgetReaderGroup;
|
|
break;
|
|
case CComObject::ForgetReaderGroup_response:
|
|
pCom = new ComForgetReaderGroup;
|
|
break;
|
|
case CComObject::IntroduceReader_request:
|
|
pCom = new ComIntroduceReader;
|
|
break;
|
|
case CComObject::IntroduceReader_response:
|
|
pCom = new ComIntroduceReader;
|
|
break;
|
|
case CComObject::ForgetReader_request:
|
|
pCom = new ComForgetReader;
|
|
break;
|
|
case CComObject::ForgetReader_response:
|
|
pCom = new ComForgetReader;
|
|
break;
|
|
case CComObject::AddReaderToGroup_request:
|
|
pCom = new ComAddReaderToGroup;
|
|
break;
|
|
case CComObject::AddReaderToGroup_response:
|
|
pCom = new ComAddReaderToGroup;
|
|
break;
|
|
case CComObject::RemoveReaderFromGroup_request:
|
|
pCom = new ComRemoveReaderFromGroup;
|
|
break;
|
|
case CComObject::RemoveReaderFromGroup_response:
|
|
pCom = new ComRemoveReaderFromGroup;
|
|
break;
|
|
case CComObject::IntroduceCardType_request:
|
|
pCom = new ComIntroduceCardType;
|
|
break;
|
|
case CComObject::IntroduceCardType_response:
|
|
pCom = new ComIntroduceCardType;
|
|
break;
|
|
case CComObject::ForgetCardType_request:
|
|
pCom = new ComForgetCardType;
|
|
break;
|
|
case CComObject::ForgetCardType_response:
|
|
pCom = new ComForgetCardType;
|
|
break;
|
|
case CComObject::FreeMemory_request:
|
|
pCom = new ComFreeMemory;
|
|
break;
|
|
case CComObject::FreeMemory_response:
|
|
pCom = new ComFreeMemory;
|
|
break;
|
|
case CComObject::Cancel_request:
|
|
pCom = new ComCancel;
|
|
break;
|
|
case CComObject::Cancel_response:
|
|
pCom = new ComCancel;
|
|
break;
|
|
#endif
|
|
case CComObject::LocateCards_request:
|
|
pCom = new ComLocateCards;
|
|
break;
|
|
case CComObject::LocateCards_response:
|
|
pCom = new ComLocateCards;
|
|
break;
|
|
case CComObject::GetStatusChange_request:
|
|
pCom = new ComGetStatusChange;
|
|
break;
|
|
case CComObject::GetStatusChange_response:
|
|
pCom = new ComGetStatusChange;
|
|
break;
|
|
case CComObject::Connect_request:
|
|
pCom = new ComConnect;
|
|
break;
|
|
case CComObject::Connect_response:
|
|
pCom = new ComConnect;
|
|
break;
|
|
case CComObject::Reconnect_request:
|
|
pCom = new ComReconnect;
|
|
break;
|
|
case CComObject::Reconnect_response:
|
|
pCom = new ComReconnect;
|
|
break;
|
|
case CComObject::Disconnect_request:
|
|
pCom = new ComDisconnect;
|
|
break;
|
|
case CComObject::Disconnect_response:
|
|
pCom = new ComDisconnect;
|
|
break;
|
|
case CComObject::BeginTransaction_request:
|
|
pCom = new ComBeginTransaction;
|
|
break;
|
|
case CComObject::BeginTransaction_response:
|
|
pCom = new ComBeginTransaction;
|
|
break;
|
|
case CComObject::EndTransaction_request:
|
|
pCom = new ComEndTransaction;
|
|
break;
|
|
case CComObject::EndTransaction_response:
|
|
pCom = new ComEndTransaction;
|
|
break;
|
|
case CComObject::Status_request:
|
|
pCom = new ComStatus;
|
|
break;
|
|
case CComObject::Status_response:
|
|
pCom = new ComStatus;
|
|
break;
|
|
case CComObject::Transmit_request:
|
|
pCom = new ComTransmit;
|
|
break;
|
|
case CComObject::Transmit_response:
|
|
pCom = new ComTransmit;
|
|
break;
|
|
case CComObject::OpenReader_request:
|
|
pCom = new ComOpenReader;
|
|
break;
|
|
case CComObject::OpenReader_response:
|
|
pCom = new ComOpenReader;
|
|
break;
|
|
case CComObject::Control_request:
|
|
pCom = new ComControl;
|
|
break;
|
|
case CComObject::Control_response:
|
|
pCom = new ComControl;
|
|
break;
|
|
case CComObject::GetAttrib_request:
|
|
pCom = new ComGetAttrib;
|
|
break;
|
|
case CComObject::GetAttrib_response:
|
|
pCom = new ComGetAttrib;
|
|
break;
|
|
case CComObject::SetAttrib_request:
|
|
pCom = new ComSetAttrib;
|
|
break;
|
|
case CComObject::SetAttrib_response:
|
|
pCom = new ComSetAttrib;
|
|
break;
|
|
default:
|
|
CalaisWarning(
|
|
DBGT("ReceiveComObject"),
|
|
DBGT("Invalid Comm Object Id on pipe"));
|
|
throw (DWORD)SCARD_F_COMM_ERROR;
|
|
}
|
|
|
|
if (0 == (rgdwInData[0] & 0x01)) // Request or response?
|
|
pCom->m_pbfActive = &pCom->m_bfRequest;
|
|
else
|
|
pCom->m_pbfActive = &pCom->m_bfResponse;
|
|
|
|
|
|
//
|
|
// Pull it in.
|
|
//
|
|
|
|
pCom->m_pbfActive->Resize(rgdwInData[1]);
|
|
CopyMemory(
|
|
pCom->m_pbfActive->Access(),
|
|
rgdwInData,
|
|
sizeof(rgdwInData));
|
|
fSts = ReadFile(
|
|
hFile,
|
|
pCom->m_pbfActive->Access(sizeof(rgdwInData)),
|
|
rgdwInData[1] - sizeof(rgdwInData),
|
|
&dwLen,
|
|
NULL);
|
|
if (!fSts)
|
|
{
|
|
DWORD dwSts = GetLastError();
|
|
cerr << TEXT("Can't read input file: ")
|
|
<< ErrorString(dwSts);
|
|
throw dwSts;
|
|
}
|
|
}
|
|
|
|
catch (...)
|
|
{
|
|
if (NULL != pCom)
|
|
{
|
|
delete pCom;
|
|
pCom = NULL;
|
|
}
|
|
}
|
|
|
|
return pCom;
|
|
}
|
|
|