using System;
using System.Runtime.InteropServices;
using SCARDSSPLib;
using GemCardExLib;
namespace GemCard
{
///
/// Implements the ICard interface using the SCard COM objects from Microsoft and SCardDatabaseEx object
/// for the ListReaders function.
///
public class CardCOM : CardBase
{
private ISCard m_itfCard = null;
///
/// Default constructor
///
public CardCOM()
{
// Create the SCard object
m_itfCard = new CSCardClass();
}
#region ICard Members
///
/// Wraps the PCSC function
/// LONG SCardListReaders(SCARDCONTEXT hContext,
/// LPCTSTR mszGroups,
/// LPTSTR mszReaders,
/// LPDWORD pcchReaders
/// );
///
/// A string array of the readers
public override string[] ListReaders()
{
ISCardDatabaseEx itfCardBase = new SCardDatabaseEx();
return (string[]) itfCardBase.ListReaders();
}
///
/// Wraps the PCSC function
/// LONG SCardConnect(
/// IN SCARDCONTEXT hContext,
/// IN LPCTSTR szReader,
/// IN DWORD dwShareMode,
/// IN DWORD dwPreferredProtocols,
/// OUT LPSCARDHANDLE phCard,
/// OUT LPDWORD pdwActiveProtocol
/// );
///
///
///
///
public override void Connect(string Reader, SHARE ShareMode, PROTOCOL PreferredProtocols)
{
// Calls AttachReader to connect to the card
m_itfCard.AttachByReader(Reader, (SCARD_SHARE_MODES) ShareMode, (SCARD_PROTOCOLS) PreferredProtocols);
}
///
/// Wraps the PCSC function
/// LONG SCardDisconnect(
/// IN SCARDHANDLE hCard,
/// IN DWORD dwDisposition
/// );
///
///
public override void Disconnect(DISCONNECT Disposition)
{
// Off the connection with the card
m_itfCard.Detach((SCARD_DISPOSITIONS) Disposition);
}
///
/// Wraps the PCSC function
/// LONG SCardTransmit(
/// SCARDHANDLE hCard,
/// LPCSCARD_I0_REQUEST pioSendPci,
/// LPCBYTE pbSendBuffer,
/// DWORD cbSendLength,
/// LPSCARD_IO_REQUEST pioRecvPci,
/// LPBYTE pbRecvBuffer,
/// LPDWORD pcbRecvLength
/// );
///
/// APDUCommand object with the APDU to send to the card
/// An APDUResponse object with the response from the card
public override APDUResponse Transmit(APDUCommand ApduCmd)
{
CSCardCmd itfCmd = new CSCardCmdClass();
CByteBuffer itfData = new CByteBufferClass();
int nLe = ApduCmd.Le;
if (ApduCmd.Data == null)
{
itfData.SetSize(0);
}
else
{
int nWrite = 0;
itfData.SetSize(ApduCmd.Data.Length);
itfData.Write(ref ApduCmd.Data[0], ApduCmd.Data.Length, ref nWrite);
}
// Build the APDU command
itfCmd.BuildCmd(ApduCmd.Class, ApduCmd.Ins, ApduCmd.P1, ApduCmd.P2, itfData, ref nLe);
// Send the command
m_itfCard.Transaction(ref itfCmd);
// Analyse the response
int nRead = 0;
byte[] pbResp = new byte[itfCmd.ApduReplyLength];
itfCmd.ApduReply.Read(ref pbResp[0], itfCmd.ApduReplyLength, ref nRead);
return new APDUResponse(pbResp);
}
///
/// Wraps the PSCS function
/// LONG SCardBeginTransaction(
/// SCARDHANDLE hCard
// );
/// This function is not supported in the COM implementation
///
public override void BeginTransaction()
{
throw new NotImplementedException("BeginTransaction is not supported in the COM implementation");
}
///
/// Wraps the PCSC function
/// LONG SCardEndTransaction(
/// SCARDHANDLE hCard,
/// DWORD dwDisposition
/// );
/// This function is not supported in the COM implementation
///
/// A value from DISCONNECT enum
public override void EndTransaction(DISCONNECT Disposition)
{
throw new NotImplementedException("EndTransaction is not supported in the COM implementation");
}
///
/// Gets the attributes of the card
///
/// Identifier for the Attribute to get
/// Attribute content
public override byte[] GetAttribute(UInt32 AttribId)
{
throw new NotImplementedException();
}
#endregion
///
/// This function must implement a card detection mechanism.
///
/// When card insertion is detected, it must call the method CardInserted()
/// When card removal is detected, it must call the method CardRemoved()
///
///
protected override void RunCardDetection(object Reader)
{
throw new Exception("The method or operation is not implemented.");
}
}
}