📄 pscrcb.c
字号:
/*++
Copyright (c) 1997 - 1999 SCM Microsystems, Inc.
Module Name:
PscrCB.c
Abstract:
callback handler for PSCR.xxx driver
Author:
Andreas Straub
Environment:
Win 95 Sys... calls are resolved by Pscr95Wrap.asm functions and
Pscr95Wrap.h macros, resp.
NT 4.0 Sys... functions resolved by PscrNTWrap.c functions and
PscrNTWrap.h macros, resp.
Revision History:
Andreas Straub 8/18/1997 1.00 Initial Version
Andreas Straub 9/24/1997 1.02 Flush Interface if card tracking
requested
--*/
#if defined( SMCLIB_VXD )
#include <Pscr95.h>
#else // SMCLIB_VXD
#include <PscrNT.h>
#endif // SMCLIB_VXD
#include <PscrRdWr.h>
#include <PscrCmd.h>
#include <PscrCB.h>
NTSTATUS
CBCardPower(
PSMARTCARD_EXTENSION SmartcardExtension
)
/*++
CBCardPower:
callback handler for SMCLIB RDF_CARD_POWER
Arguments:
SmartcardExtension context of call
Return Value:
STATUS_SUCCESS
STATUS_NO_MEDIA
STATUS_TIMEOUT
STATUS_BUFFER_TOO_SMALL
--*/
{
NTSTATUS NTStatus = STATUS_SUCCESS;
UCHAR ATRBuffer[ ATR_SIZE ], TLVList[16];
ULONG Command,
ATRLength;
PREADER_EXTENSION ReaderExtension;
BYTE CardState;
#if DBG || DEBUG
static PCHAR request[] = { "PowerDown", "ColdReset", "WarmReset" };
#endif
SmartcardDebug(
DEBUG_TRACE,
( "PSCR!CBCardPower: Enter, Request = %s\n",
request[SmartcardExtension->MinorIoControlCode])
);
ReaderExtension = SmartcardExtension->ReaderExtension;
//
// update actual power state
//
Command = SmartcardExtension->MinorIoControlCode;
switch ( Command )
{
case SCARD_WARM_RESET:
// if the card was not powerd, fall thru to cold reset
if( SmartcardExtension->ReaderCapabilities.CurrentState >
SCARD_SWALLOWED )
{
// reset the card
ATRLength = ATR_SIZE;
NTStatus = CmdReset(
ReaderExtension,
ReaderExtension->Device,
TRUE, // warm reset
ATRBuffer,
&ATRLength
);
break;
}
// warm reset not possible because card was not powerd
case SCARD_COLD_RESET:
// reset the card
ATRLength = ATR_SIZE;
NTStatus = CmdReset(
ReaderExtension,
ReaderExtension->Device,
FALSE, // cold reset
ATRBuffer,
&ATRLength
);
break;
case SCARD_POWER_DOWN:
ATRLength = 0;
NTStatus = CmdDeactivate(
ReaderExtension,
ReaderExtension->Device
);
// discard old card status
CardState = CBGetCardState(SmartcardExtension);
CBUpdateCardState(SmartcardExtension, CardState, FALSE);
break;
}
if (NTStatus == STATUS_SUCCESS) {
//
// Set the 'restart of work waiting time' counter for T=0
// This will send a WTX request for n NULL bytes received
//
TLVList[0] = TAG_SET_NULL_BYTES;
TLVList[1] = 1;
TLVList[2] = 0x05;
NTStatus = CmdSetInterfaceParameter(
ReaderExtension,
DEVICE_READER,
TLVList,
3
);
}
ASSERT(NTStatus == STATUS_SUCCESS);
// finish the request
if( NT_SUCCESS( NTStatus ))
{
// update all neccessary data if an ATR was received
if( ATRLength > 2 )
{
//
// the lib expects only the ATR, so we skip the
// 900x from the reader
//
ATRLength -= 2;
// copy ATR to user buffer buffer
if( ATRLength <= SmartcardExtension->IoRequest.ReplyBufferLength )
{
SysCopyMemory(
SmartcardExtension->IoRequest.ReplyBuffer,
ATRBuffer,
ATRLength
);
*SmartcardExtension->IoRequest.Information = ATRLength;
}
else
{
NTStatus = STATUS_BUFFER_TOO_SMALL;
}
// copy ATR to card capability buffer
if( ATRLength <= MAXIMUM_ATR_LENGTH )
{
SysCopyMemory(
SmartcardExtension->CardCapabilities.ATR.Buffer,
ATRBuffer,
ATRLength
);
SmartcardExtension->CardCapabilities.ATR.Length =
( UCHAR )ATRLength;
// let the lib update the card capabilities
NTStatus = SmartcardUpdateCardCapabilities(
SmartcardExtension
);
}
else
{
NTStatus = STATUS_BUFFER_TOO_SMALL;
}
}
}
if( !NT_SUCCESS( NTStatus ))
{
switch( NTStatus )
{
case STATUS_NO_MEDIA:
case STATUS_BUFFER_TOO_SMALL:
break;
case STATUS_TIMEOUT:
NTStatus = STATUS_IO_TIMEOUT;
break;
default:
NTStatus = STATUS_UNRECOGNIZED_MEDIA;
break;
}
}
SmartcardDebug(
DEBUG_TRACE,
( "PSCR!CBCardPower: Exit (%lx)\n", NTStatus )
);
return( NTStatus );
}
NTSTATUS
CBSetProtocol(
PSMARTCARD_EXTENSION SmartcardExtension
)
/*++
CBSetProtocol:
callback handler for SMCLIB RDF_SET_PROTOCOL
Arguments:
SmartcardExtension context of call
Return Value:
STATUS_SUCCESS
STATUS_NO_MEDIA
STATUS_TIMEOUT
STATUS_BUFFER_TOO_SMALL
STATUS_INVALID_DEVICE_STATE
STATUS_INVALID_DEVICE_REQUEST
--*/
{
NTSTATUS NTStatus = STATUS_PENDING;
USHORT SCLibProtocol;
UCHAR TLVList[ TLV_BUFFER_SIZE ];
PREADER_EXTENSION ReaderExtension = SmartcardExtension->ReaderExtension;
if (SmartcardExtension->ReaderCapabilities.CurrentState == SCARD_SPECIFIC) {
return STATUS_SUCCESS;
}
SmartcardDebug(
DEBUG_TRACE,
( "PSCR!CBSetProtocol: Enter\n" )
);
SCLibProtocol = ( USHORT )( SmartcardExtension->MinorIoControlCode );
if (SCLibProtocol & (SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1))
{
//
// setup the TLV list for the Set Interface Parameter List
//
TLVList[ 0 ] = TAG_ICC_PROTOCOLS;
TLVList[ 1 ] = 0x01;
TLVList[ 2 ] =
(SCLibProtocol & SCARD_PROTOCOL_T1 ? PSCR_PROTOCOL_T1 : PSCR_PROTOCOL_T0);
// do the PTS
NTStatus = CmdSetInterfaceParameter(
ReaderExtension,
ReaderExtension->Device,
TLVList,
3 // size of list
);
} else {
// we don't support other modi
NTStatus = STATUS_INVALID_DEVICE_REQUEST;
}
// if protocol selection failed, prevent from calling invalid protocols
if( NT_SUCCESS( NTStatus ))
{
SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_SPECIFIC;
SCLibProtocol = (SCLibProtocol & SCARD_PROTOCOL_T1 &
SmartcardExtension->CardCapabilities.Protocol.Supported) ?
SCARD_PROTOCOL_T1 :
SCARD_PROTOCOL_T0;
}
else
{
SCLibProtocol = SCARD_PROTOCOL_UNDEFINED;
}
// Return the selected protocol to the caller.
SmartcardExtension->CardCapabilities.Protocol.Selected = SCLibProtocol;
*( PULONG )( SmartcardExtension->IoRequest.ReplyBuffer ) = SCLibProtocol;
*( SmartcardExtension->IoRequest.Information ) = sizeof( ULONG );
SmartcardDebug(
DEBUG_TRACE,
( "PSCR!CBSetProtocol: Exit (%lx)\n", NTStatus )
);
return ( NTStatus );
}
NTSTATUS
CBTransmit(
PSMARTCARD_EXTENSION SmartcardExtension
)
/*++
CBTransmit:
callback handler for SMCLIB RDF_TRANSMIT
Arguments:
SmartcardExtension context of call
Return Value:
STATUS_SUCCESS
STATUS_NO_MEDIA
STATUS_TIMEOUT
STATUS_INVALID_DEVICE_REQUEST
--*/
{
NTSTATUS NTStatus = STATUS_SUCCESS;
SmartcardDebug(
DEBUG_TRACE,
( "PSCR!CBTransmit: Enter\n" )
);
// dispatch on the selected protocol
switch( SmartcardExtension->CardCapabilities.Protocol.Selected )
{
case SCARD_PROTOCOL_T0:
NTStatus = CBT0Transmit( SmartcardExtension );
break;
case SCARD_PROTOCOL_T1:
NTStatus = CBT1Transmit( SmartcardExtension );
break;
case SCARD_PROTOCOL_RAW:
NTStatus = CBRawTransmit( SmartcardExtension );
break;
default:
NTStatus = STATUS_INVALID_DEVICE_REQUEST;
break;
}
SmartcardDebug(
DEBUG_TRACE,
( "PSCR!CBTransmit: Exit (%lx)\n", NTStatus )
);
return( NTStatus );
}
NTSTATUS
CBRawTransmit(
PSMARTCARD_EXTENSION SmartcardExtension
)
/*++
CBRawTransmit:
finishes the callback RDF_TRANSMIT for the RAW protocol
Arguments:
SmartcardExtension context of call
Return Value:
STATUS_SUCCESS
STATUS_NO_MEDIA
STATUS_TIMEOUT
STATUS_INVALID_DEVICE_REQUEST
--*/
{
NTSTATUS NTStatus = STATUS_SUCCESS;
UCHAR TLVList[ TLV_BUFFER_SIZE ],
Val,
Len;
ULONG TLVListLen;
PREADER_EXTENSION ReaderExtension;
SmartcardDebug(
DEBUG_TRACE,
( "PSCR!CBRawTransmit: Enter\n" )
);
ReaderExtension = SmartcardExtension->ReaderExtension;
//
// read the status file of ICC1 from the reader
//
TLVListLen = TLV_BUFFER_SIZE;
NTStatus = CmdReadStatusFile(
ReaderExtension,
ReaderExtension->Device,
TLVList,
&TLVListLen
);
//
// check the active protocol of the reader
//
if( NT_SUCCESS( NTStatus ))
{
NTStatus = CmdGetTagValue(
TAG_ICC_PROTOCOLS,
TLVList,
TLVListLen,
&Len,
( PVOID ) &Val
);
// execute the active protocol
if( NT_SUCCESS( NTStatus ))
{
// translate the actual protocol to a value the lib can understand
switch( Val )
{
case PSCR_PROTOCOL_T0:
NTStatus = CBT0Transmit( SmartcardExtension );
break;
case PSCR_PROTOCOL_T1:
NTStatus = CBT1Transmit( SmartcardExtension );
break;
default:
NTStatus = STATUS_UNSUCCESSFUL;
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -