📄 simcb.c
字号:
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//------------------------------------------------------------------------------
//
// Copyright (C) 2004, Motorola Inc. All Rights Reserved
//
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//
// File: simcb.c
//
// This file implements the call back functions for sim
//
//------------------------------------------------------------------------------
// Include
#include <windows.h>
#include <devload.h>
#include <smclib.h>
#include <winsmcrd.h>
#include "mxarm11.h"
#include "simcb.h"
#include "simhw.h"
//------------------------------------------------------------------------------
// External Functions
//------------------------------------------------------------------------------
// External Variables
//------------------------------------------------------------------------------
// Defines
//------------------------------------------------------------------------------
// Types
//------------------------------------------------------------------------------
// Global Variables
//------------------------------------------------------------------------------
// Local Variables
//------------------------------------------------------------------------------
// Local Functions
static NTSTATUS CBT0Transmit(PSMARTCARD_EXTENSION SmartcardExtension);
static NTSTATUS T0_ExchangeData(
PREADER_EXTENSION ReaderExtension,
PUCHAR pRequest,
ULONG RequestLen,
PUCHAR pReply,
PULONG pReplyLen);
static NTSTATUS CBSynchronizeSIM(PSMARTCARD_EXTENSION SmartcardExtension );
//-----------------------------------------------------------------------------
//
// Function: CBCardPower
//
// This function is the callback handler for SMCLIB RDF_CARD_POWER
//
// Parameters:
// SmartcardExtension
// [in]Pointer of the context of call
//
// Returns:
// NTSTATUS:
// STATUS_SUCCESS
// STATUS_NO_MEDIA
// STATUS_TIMEOUT
// STATUS_BUFFER_TOO_SMALL
//
//-----------------------------------------------------------------------------
NTSTATUS CBCardPower(PSMARTCARD_EXTENSION SmartcardExtension)
{
NTSTATUS NTStatus = STATUS_SUCCESS;
UCHAR ATRBuffer[ ATR_SIZE ];
ULONG Command, ATRLength;
PCSP_SIM_REG pSIMReg;
#if DBG || DEBUG
static PTCHAR request[] = { TEXT("PowerDown"), TEXT("ColdReset"), TEXT("WarmReset") };
#endif
SmartcardDebug(DEBUG_TRACE, ( TEXT("+CBCardPower, Request = %s\n"),request[SmartcardExtension->MinorIoControlCode]));
pSIMReg = SmartcardExtension->ReaderExtension->pSIMReg;
//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 )
{
NTStatus = SIM_WarmReset(SmartcardExtension->ReaderExtension->pSIMReg);
break;
}
case SCARD_COLD_RESET:
//reset the card
ATRLength = ATR_SIZE;
NTStatus = SIM_ColdReset(SmartcardExtension->ReaderExtension->pSIMReg, ATRBuffer, &ATRLength);
SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_SPECIFIC;
break;
case SCARD_POWER_DOWN:
ATRLength = 0;
NTStatus = SIM_Deactivate(SmartcardExtension->ReaderExtension->pSIMReg);
if(NTStatus == STATUS_SUCCESS)
{
SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_PRESENT;
}
break;
}
// finish the request
if( NTStatus == STATUS_SUCCESS )
{
// update all neccessary data if an ATR was received
if( ATRLength > 2 )
{
// copy ATR to user 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 <= 64 )
{
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;
}
}
}
SmartcardDebug( DEBUG_TRACE,( TEXT("-CBCardPower Exit: %X\n"), NTStatus ));
return( NTStatus );
}
//-----------------------------------------------------------------------------
//
// Function: CBSetProtocol
//
// This function is the callback handler for SMCLIB RDF_SET_PROTOCOL
//
// Parameters:
// SmartcardExtension
// [in]Pointer of the context of call
//
// Returns:
// NTSTATUS:
// STATUS_SUCCESS
// STATUS_NO_MEDIA
// STATUS_TIMEOUT
// STATUS_BUFFER_TOO_SMALL
// STATUS_INVALID_DEVICE_STATE
// STATUS_INVALID_DEVICE_REQUEST
//
//-----------------------------------------------------------------------------
NTSTATUS CBSetProtocol(PSMARTCARD_EXTENSION SmartcardExtension)
{
NTSTATUS NTStatus = STATUS_PENDING;
UCHAR PTSRequest[64],
PTSReply[64];
ULONG NewProtocol;
SmartcardDebug(DEBUG_TRACE, (TEXT("+CBSetProtocol Enter\n")));
NewProtocol = SmartcardExtension->MinorIoControlCode;
// check if the card is already in specific state
if( ( SmartcardExtension->ReaderCapabilities.CurrentState == SCARD_SPECIFIC ) &&
( SmartcardExtension->CardCapabilities.Protocol.Selected & NewProtocol ))
{
NTStatus = STATUS_SUCCESS;
}
// protocol supported?
if( !( SmartcardExtension->CardCapabilities.Protocol.Supported & NewProtocol ) ||
!( SmartcardExtension->ReaderCapabilities.SupportedProtocols & NewProtocol ))
{
NTStatus = STATUS_INVALID_DEVICE_REQUEST;
}
// send PTS
while( NTStatus == STATUS_PENDING )
{
//flush the SIM fifo
SIM_FlushFIFO(SmartcardExtension->ReaderExtension->pSIMReg);
// set initial character of PTS
PTSRequest[0] = 0xFF;
// set the format character
if(( NewProtocol & SCARD_PROTOCOL_T1 )&&
(SmartcardExtension->CardCapabilities.Protocol.Supported & SCARD_PROTOCOL_T1 ))
{
PTSRequest[1] = 0x11;
SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_T1;
}
else
{
PTSRequest[1] = 0x10;
SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_T0;
}
// PTS1 codes Fl and Dl
PTSRequest[2] =
SmartcardExtension->CardCapabilities.PtsData.Fl << 4 |
SmartcardExtension->CardCapabilities.PtsData.Dl;
// check character
PTSRequest[3] = PTSRequest[0] ^ PTSRequest[1] ^ PTSRequest[2];
// write PTSRequest
NTStatus = SIM_WriteData(SmartcardExtension->ReaderExtension->pSIMReg, PTSRequest, 4);
// get response
if( NTStatus == STATUS_SUCCESS )
{
NTStatus = SIM_ReadData(SmartcardExtension->ReaderExtension->pSIMReg, PTSReply, 2 );
if( PTSReply[1] == 0)
NTStatus = SIM_ReadData(SmartcardExtension->ReaderExtension->pSIMReg, (PTSReply + 2), 1 );
else
NTStatus = SIM_ReadData(SmartcardExtension->ReaderExtension->pSIMReg, (PTSReply + 2), 2 );
if(( NTStatus == STATUS_SUCCESS ) && !SysCompareMemory( PTSRequest, PTSReply, 4))
{
// set the SIM registers
SmartcardExtension->CardCapabilities.Dl =
SmartcardExtension->CardCapabilities.PtsData.Dl;
SmartcardExtension->CardCapabilities.Fl =
SmartcardExtension->CardCapabilities.PtsData.Fl;
NTStatus = CBSynchronizeSIM( SmartcardExtension );
// the card replied correctly to the PTS-request
break;
}
}
//
// The card did either NOT reply or it replied incorrectly
// so try default values
//
if( SmartcardExtension->CardCapabilities.PtsData.Type != PTS_TYPE_DEFAULT )
{
SmartcardExtension->CardCapabilities.PtsData.Type = PTS_TYPE_DEFAULT;
SmartcardExtension->MinorIoControlCode = SCARD_COLD_RESET;
NTStatus = CBCardPower( SmartcardExtension );
if( NTStatus == STATUS_SUCCESS )
{
NTStatus = STATUS_PENDING;
}
else
{
NTStatus = STATUS_DEVICE_PROTOCOL_ERROR;
}
}
}
if( NTStatus == STATUS_TIMEOUT )
{
NTStatus = STATUS_IO_TIMEOUT;
}
if( NTStatus == STATUS_SUCCESS )
{
// indicate that the card is in specific mode
SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_SPECIFIC;
// return the selected protocol to the caller
*(PULONG) SmartcardExtension->IoRequest.ReplyBuffer = SmartcardExtension->CardCapabilities.Protocol.Selected;
*SmartcardExtension->IoRequest.Information = sizeof(SmartcardExtension->CardCapabilities.Protocol.Selected);
}
else
{
SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_UNDEFINED;
*(PULONG) SmartcardExtension->IoRequest.ReplyBuffer = 0;
*SmartcardExtension->IoRequest.Information = 0;
}
SmartcardDebug( DEBUG_TRACE, (TEXT("-CBSetProtocol: Exit %X\n"), NTStatus ));
return( NTStatus );
}
//-----------------------------------------------------------------------------
//
// Function: CBTransmit
//
// This function is the callback handler for SMCLIB RDF_TRANSMIT
//
// Parameters:
// SmartcardExtension
// [in]Pointer of the context of call
//
// Returns:
// NTSTATUS:
// STATUS_SUCCESS
// STATUS_NO_MEDIA
// STATUS_TIMEOUT
// STATUS_INVALID_DEVICE_REQUEST
//
//-----------------------------------------------------------------------------
NTSTATUS CBTransmit(PSMARTCARD_EXTENSION SmartcardExtension)
{
NTSTATUS NTStatus = STATUS_SUCCESS;
SmartcardDebug( DEBUG_TRACE, (TEXT("+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:
SmartcardDebug(DEBUG_ERROR,( TEXT("T1 protocol is not supported in this driver!\n")));
return (STATUS_UNSUCCESSFUL);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -