📄 pscrcmd.c
字号:
}
}
}
}
return( NTStatus );
}
NTSTATUS
CmdSelectFile(
PREADER_EXTENSION ReaderExtension,
USHORT FileId
)
/*++
CmdSelectFile:
selects a file/directoy of the reader
Arguments:
ReaderExtension context of call
FileId ID of file
Return Value:
STATUS_SUCCESS
STATUS_UNSUCCESSFUL
error values from PscrRead / PscrWrite
--*/
{
NTSTATUS NTStatus = STATUS_SUCCESS;
UCHAR IOData[ MAX_T1_BLOCK_SIZE ];
USHORT ICCStatus;
ULONG IOBytes;
//
// build the SELECT FILE command
//
IOData[ PSCR_NAD ] = NAD_TO_PSCR;
IOData[ PSCR_PCB ] = PCB_DEFAULT;
IOData[ PSCR_LEN ] = 0x07;
IOData[ PSCR_INF+0 ] = CLA_SELECT_FILE;
IOData[ PSCR_INF+1 ] = INS_SELECT_FILE;
IOData[ PSCR_INF+2 ] = 0x00;
IOData[ PSCR_INF+3 ] = 0x00;
IOData[ PSCR_INF+4 ] = 0x02;
IOData[ PSCR_INF+5 ] = HIBYTE( FileId );
IOData[ PSCR_INF+6 ] = LOBYTE( FileId );
//
// write command
//
NTStatus = PscrWrite(
ReaderExtension,
IOData,
10,
&IOBytes
);
if( NT_SUCCESS( NTStatus ))
{
//
// get the response of the reader
//
IOBytes = 0;
NTStatus = PscrRead(
ReaderExtension,
IOData,
MAX_T1_BLOCK_SIZE,
&IOBytes
);
if( NT_SUCCESS( NTStatus ))
{
//
// check errors
//
ICCStatus =
((USHORT)IOData[ IOBytes-2-PSCR_EPILOGUE_LENGTH ]) << 8;
ICCStatus |=
(USHORT)IOData[ IOBytes-1-PSCR_EPILOGUE_LENGTH ];
if( ICCStatus == PSCR_SW_FILE_NOT_FOUND )
{
NTStatus = STATUS_UNSUCCESSFUL;
}
}
}
return( NTStatus );
}
NTSTATUS
CmdSetInterfaceParameter(
PREADER_EXTENSION ReaderExtension,
UCHAR Device,
PUCHAR pTLVList,
UCHAR TLVListLen
)
/*++
CmdSetInterfaceParameter:
Sets the interface pareameter of the ICC interface to the values specified
in the TLV list
Arguments:
ReaderExtension context of call
Device device
pTLVList ptr to list of tag-len-value's specified by caller
TLVListLen length of list
Return Value:
STATUS_SUCCESS
STATUS_INVALID_PARAMETER
STATUS_INVALID_DEVICE_STATE
error values from PscrRead / PscrWrite
--*/
{
NTSTATUS NTStatus = STATUS_SUCCESS;
UCHAR IOData[ MAX_T1_BLOCK_SIZE ];
USHORT ICCStatus;
ULONG IOBytes;
//
// check parameter
//
if( pTLVList == NULL )
{
NTStatus = STATUS_INVALID_PARAMETER;
}
else
{
//
// build the SET INTERFACE PARAMETER command
//
IOData[ PSCR_NAD ] = NAD_TO_PSCR;
IOData[ PSCR_PCB ] = PCB_DEFAULT;
IOData[ PSCR_LEN ] = 0x05 + TLVListLen;
IOData[ PSCR_INF+0 ] = CLA_SET_INTERFACE_PARAM;
IOData[ PSCR_INF+1 ] = INS_SET_INTERFACE_PARAM;
IOData[ PSCR_INF+2 ] = Device;
IOData[ PSCR_INF+3 ] = 0x00;
IOData[ PSCR_INF+4 ] = TLVListLen;
SysCopyMemory( &IOData[ PSCR_INF+5 ], pTLVList, TLVListLen );
//
// write command
//
NTStatus = PscrWrite(
ReaderExtension,
IOData,
8 + TLVListLen,
&IOBytes
);
if( NT_SUCCESS( NTStatus ))
{
// do an dummy read to catch errors.
IOBytes = 0;
NTStatus = PscrRead(
ReaderExtension,
IOData,
MAX_T1_BLOCK_SIZE,
&IOBytes
);
if( NT_SUCCESS( NTStatus ))
{
// check error
ICCStatus =
((USHORT)IOData[ IOBytes - 2 - PSCR_EPILOGUE_LENGTH ]) << 8;
ICCStatus |=
(USHORT)IOData[ IOBytes - 1 - PSCR_EPILOGUE_LENGTH ];
if( ICCStatus != 0x9000 )
{
NTStatus = STATUS_INVALID_DEVICE_STATE;
}
}
}
}
return( NTStatus );
}
NTSTATUS
CmdReadStatusFile (
PREADER_EXTENSION ReaderExtension,
UCHAR Device,
PUCHAR pTLVList,
PULONG pTLVListLen
)
/*++
CmdReadStatusFile:
read the status file of the requested device from the reader filesystem
Arguments:
ReaderExtension context of call
Device requested device
pTLVList ptr to list (i.e. the status file)
pTLVListLen length of buffer / returned list
Return Value:
STATUS_SUCCESS
STATUS_BUFFER_TOO_SMALL
error values from PscrRead / PscrWrite
--*/
{
NTSTATUS NTStatus = STATUS_UNSUCCESSFUL;
UCHAR IOData[ MAX_T1_BLOCK_SIZE ];
ULONG IOBytes;
// select ICC status file if it's not the active file
if( ReaderExtension->StatusFileSelected == FALSE )
{
// select master file on reader
NTStatus = CmdSelectFile( ReaderExtension, FILE_MASTER );
// select ICC directory
if( NT_SUCCESS( NTStatus ))
{
if( Device != DEVICE_ICC1 )
{
NTStatus = STATUS_UNSUCCESSFUL;
}
else
{
NTStatus = CmdSelectFile(
ReaderExtension,
FILE_ICC1_DIR
);
// select status file
if( NT_SUCCESS( NTStatus ))
{
NTStatus = CmdSelectFile(
ReaderExtension,
FILE_ICC1_DIR_STATUS
);
if( NT_SUCCESS( NTStatus ))
{
ReaderExtension->StatusFileSelected = TRUE;
}
}
}
}
}
// read status file if successful selected
if( ReaderExtension->StatusFileSelected == TRUE )
{
IOBytes = MAX_T1_BLOCK_SIZE;
NTStatus = CmdReadBinary(
ReaderExtension,
0,
IOData,
&IOBytes
);
// copy data to user buffer
if( NT_SUCCESS( NTStatus ))
{
if(( pTLVList != NULL ) && ( IOBytes < *pTLVListLen ))
{
*pTLVListLen = IOBytes;
SysCopyMemory( pTLVList, IOData, IOBytes );
}
else
{
NTStatus = STATUS_BUFFER_TOO_SMALL;
}
}
}
return( NTStatus );
}
NTSTATUS
CmdGetFirmwareRevision (
PREADER_EXTENSION ReaderExtension
)
/*++
CmdGetFirmwareRevision:
get the firmware revision of the reader. Ther firmware revision is found
in the PSCR configuration file (ID 0x0020) in the master directory.
The tag of the revision is 0x0F, and the value is coded as an ASCII string,
p.E. "2.20"
Arguments:
ReaderExtension context of call
Return Value:
STATUS_SUCCESS
error values from PscrRead / PscrWrite
--*/
{
NTSTATUS NTStatus = STATUS_SUCCESS;
UCHAR TLVList[ MAX_T1_BLOCK_SIZE ],
Len;
char Revision[ 0x10 ],
UpdateKey[ 0x10 ];
ULONG IOBytes;
//
// select master file on reader
//
NTStatus = CmdSelectFile( ReaderExtension, FILE_MASTER );
//
// select pscr configuration file
//
if( NT_SUCCESS( NTStatus ))
{
NTStatus = CmdSelectFile( ReaderExtension, FILE_PSCR_CONFIG );
//
// read confiuration file
//
if( NT_SUCCESS( NTStatus ))
{
IOBytes = MAX_T1_BLOCK_SIZE;
NTStatus = CmdReadBinary(
ReaderExtension,
0,
TLVList,
&IOBytes
);
//
// get the value of revison
//
if( NT_SUCCESS( NTStatus ))
{
CmdGetTagValue(
TAG_SOFTWARE_REV,
TLVList,
IOBytes,
&Len,
Revision
);
//
// the coding is always X.YY (in ASCII), so we can get the numeric
// values hardcoded by taking the low nibbles of the char's.
//
ReaderExtension->FirmwareMajor = Revision[0] & 0x0F;
ReaderExtension->FirmwareMinor = ( Revision[2] & 0x0F ) << 4;
ReaderExtension->FirmwareMinor |= Revision[3] & 0x0F;
//
// get value of update key
//
CmdGetTagValue(
TAG_UPDATE_KEY,
TLVList,
IOBytes,
&Len,
UpdateKey
);
ReaderExtension->UpdateKey = UpdateKey[0];
}
}
}
ReaderExtension->StatusFileSelected = FALSE;
return( NTStatus );
}
NTSTATUS
CmdPscrCommand (
PREADER_EXTENSION ReaderExtension,
PUCHAR pInData,
ULONG InDataLen,
PUCHAR pOutData,
ULONG OutDataLen,
PULONG pNBytes
)
/*++
CmdPscrCommand:
send a command transparent to the reader
Arguments:
ReaderExtension context of call
pInData, ptr to input buffer
InDataLen, len of input buffer
pOutData, ptr to output buffer
OutDataLen, len of output buffer
pNBytes number of bytes transferred
Return Value:
STATUS_SUCCESS
STATUS_INVALID_PARAMETER
error values from PscrRead / PscrWrite
--*/
{
NTSTATUS NTStatus = STATUS_SUCCESS;
UCHAR IOData[ MAX_T1_BLOCK_SIZE ];
ULONG IOBytes;
//
// the function is used for generic ioctl's, so carful ALL
// parametes will be checked!
//
if( ( pInData == NULL ) ||
( pOutData == NULL ) ||
( pNBytes == NULL ) ||
(InDataLen == 0 ) ||
(OutDataLen == 0 )
)
{
NTStatus = STATUS_INVALID_PARAMETER;
}
else
{
IOBytes = 0;
NTStatus = PscrWriteDirect(
ReaderExtension,
pInData,
InDataLen,
&IOBytes
);
if( NT_SUCCESS( NTStatus ))
{
//
// get result. ignore all reader errors
//
IOBytes = 0;
NTStatus = PscrRead(
ReaderExtension,
IOData,
MAX_T1_BLOCK_SIZE,
&IOBytes
);
//
// tranfer data
//
if( IOBytes > OutDataLen )
{
NTStatus = STATUS_BUFFER_TOO_SMALL;
}
else
{
*pNBytes = IOBytes;
SysCopyMemory( pOutData, IOData, IOBytes );
}
}
}
return( NTStatus );
}
NTSTATUS
CmdGetTagValue (
UCHAR Tag,
PUCHAR pTLVList,
ULONG TLVListLen,
PUCHAR pTagLen,
PVOID pTagVal
)
/*++
CmdGetTagValue:
scans a TLV list for the value of a user specified tag
it is assumed, the caller knows the kind of the requested
field, so only the ptr to the buffer will be checked
Arguments:
Tag requested Tag
pTLVList ptr to list
TLVListLen length of list
pTagLen ptr to length
pTagVal ptr to value
Return Value:
STATUS_SUCCESS
STATUS_UNSUCCESSFUL
STATUS_INVALID_PARAMETER
--*/
{
NTSTATUS NTStatus = STATUS_SUCCESS;
ULONG Idx;
//
// step through the given list
//
if(( pTLVList != NULL ) && ( pTagVal != NULL ) && ( pTagLen != NULL ))
{
//
// look for requested tag
//
Idx = 0;
while( Idx < TLVListLen )
{
if( pTLVList[ Idx ] == Tag )
{
//
// ASSUMED THE CALLER KNOWS KIND OF FIELD!!!
//
*pTagLen = pTLVList[ Idx + 1 ];
SysCopyMemory(
pTagVal,
&pTLVList[ Idx+2 ],
pTLVList[ Idx+1 ]
);
break;
}
Idx += pTLVList[ Idx+1 ] + 2;
}
if( Idx >= TLVListLen )
{
NTStatus = STATUS_UNSUCCESSFUL;
}
}
else
{
NTStatus = STATUS_INVALID_PARAMETER;
}
return( NTStatus );
}
// ------------------------------- END OF FILE -------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -