windows-nt/Source/XPSP1/NT/drivers/smartcrd/scmstcs/t0hndlr.c
2020-09-26 16:20:57 +08:00

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 ----------------------------------------