188 lines
4.5 KiB
C
188 lines
4.5 KiB
C
//+-------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
//
|
|
// Copyright (C) SCM Microsystems, 1998 - 1999
|
|
//
|
|
// File: t0hndlr.c
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
#if defined( SMCLIB_VXD )
|
|
#include "Driver98.h"
|
|
#else
|
|
#include "DriverNT.h"
|
|
#endif // SMCLIB_VXD
|
|
|
|
#include "SerialIF.h"
|
|
#include "STCCmd.h"
|
|
#include "T0Hndlr.h"
|
|
|
|
NTSTATUS
|
|
T0_ExchangeData(
|
|
PREADER_EXTENSION ReaderExtension,
|
|
PUCHAR pRequest,
|
|
ULONG RequestLen,
|
|
PUCHAR pReply,
|
|
PULONG pReplyLen
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS NTStatus = STATUS_SUCCESS;
|
|
BOOLEAN restartWorkWaitingTime = FALSE;
|
|
ULONG bytesWritten, totalBytesToWrite, totalBytesToRead;
|
|
ULONG bytesToWrite, bytesRead, ioBufferLen;
|
|
UCHAR ioBuffer[512];
|
|
|
|
totalBytesToWrite = RequestLen;
|
|
totalBytesToRead = ReaderExtension->SmartcardExtension->T0.Le + 2;
|
|
bytesRead = 0;
|
|
|
|
// start with writing the header of the request
|
|
bytesToWrite = 5;
|
|
bytesWritten = 0;
|
|
|
|
__try {
|
|
|
|
do {
|
|
|
|
if (restartWorkWaitingTime == FALSE) {
|
|
|
|
NTStatus = STCWriteICC1(
|
|
ReaderExtension,
|
|
pRequest + bytesWritten,
|
|
bytesToWrite
|
|
);
|
|
ASSERT(NTStatus != STATUS_BUFFER_TOO_SMALL);
|
|
|
|
if (NTStatus != STATUS_SUCCESS) {
|
|
|
|
__leave;
|
|
}
|
|
|
|
bytesWritten += bytesToWrite;
|
|
totalBytesToWrite -= bytesToWrite;
|
|
}
|
|
|
|
//
|
|
// try to read the pcb, the card could
|
|
// also answer with a status word
|
|
//
|
|
ioBufferLen = sizeof(ioBuffer);
|
|
NTStatus = STCReadICC1(
|
|
ReaderExtension,
|
|
ioBuffer,
|
|
&ioBufferLen,
|
|
1
|
|
);
|
|
ASSERT(NTStatus != STATUS_BUFFER_TOO_SMALL);
|
|
|
|
restartWorkWaitingTime = FALSE;
|
|
|
|
if (NTStatus != STATUS_SUCCESS) {
|
|
|
|
__leave;
|
|
}
|
|
|
|
if (ioBuffer[0] == 0x60) {
|
|
|
|
//
|
|
// Set flag that we only should read the proc byte
|
|
// without writing data to the card
|
|
//
|
|
restartWorkWaitingTime = TRUE;
|
|
continue;
|
|
}
|
|
|
|
if ((ioBuffer[0] & 0xFE) == pRequest[1]) {
|
|
|
|
// we can send all remaining bytes at once.
|
|
bytesToWrite = totalBytesToWrite;
|
|
|
|
} else if(ioBuffer[0] == (UCHAR) ~pRequest[1]) {
|
|
|
|
// we can only send the next byte
|
|
bytesToWrite = 1;
|
|
|
|
} else {
|
|
|
|
// this must be a status word
|
|
|
|
totalBytesToWrite = 0;
|
|
totalBytesToRead = 0;
|
|
|
|
pReply[0] = ioBuffer[0];
|
|
|
|
if (ioBufferLen == 2) {
|
|
|
|
//
|
|
// the reader returned already the
|
|
// 2nd byte of the status word
|
|
//
|
|
pReply[1] = ioBuffer[1];
|
|
|
|
} else {
|
|
|
|
// we have to read the 2nd byte of the status word
|
|
ioBufferLen = sizeof(ioBuffer);
|
|
NTStatus = STCReadICC1(
|
|
ReaderExtension,
|
|
ioBuffer,
|
|
&ioBufferLen,
|
|
1
|
|
);
|
|
ASSERT(NTStatus != STATUS_BUFFER_TOO_SMALL);
|
|
|
|
if (NTStatus != STATUS_SUCCESS) {
|
|
|
|
__leave;
|
|
}
|
|
if (ioBufferLen != 1) {
|
|
|
|
NTStatus = STATUS_DEVICE_PROTOCOL_ERROR;
|
|
__leave;
|
|
}
|
|
pReply[1] = ioBuffer[0];
|
|
}
|
|
|
|
*pReplyLen = 2;
|
|
}
|
|
|
|
} while (totalBytesToWrite || restartWorkWaitingTime);
|
|
|
|
if (totalBytesToRead != 0) {
|
|
|
|
ioBufferLen = *pReplyLen;
|
|
NTStatus = STCReadICC1(
|
|
ReaderExtension,
|
|
pReply,
|
|
&ioBufferLen,
|
|
totalBytesToRead
|
|
);
|
|
|
|
if (NTStatus != STATUS_SUCCESS) {
|
|
|
|
__leave;
|
|
}
|
|
|
|
*pReplyLen = ioBufferLen;
|
|
}
|
|
}
|
|
__finally {
|
|
|
|
}
|
|
|
|
return NTStatus;
|
|
}
|
|
|
|
//---------------------------------------- END OF FILE ----------------------------------------
|
|
|