Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1649 lines
29 KiB

/*++
Copyright (C) Microsoft Corporation, 1999 - 1999
Module Name:
SCardCmd
Abstract:
The ISCardCmd interface provides the methods needed to construct and manage
a smart card Application Protocol Data Unit (APDU ). This interface
encapsulates two buffers:
The APDU buffer contains the command sequence that will be sent to the
card.
The APDUReply buffer contains data returned from the card after execution
of the APDU command (this data is also referred to as the return ADPU).
The following example shows a typical use of the ISCardCmd interface. The
ISCardCmd interface is used to build the an ADPU.
To submit a transaction to a specific card
1) Create an ISCard interface and connect to a smart card.
2) Create an ISCardCmd interface.
3) Build a smart card APDU command using the ISCardISO7816 interface or
one of ISCardCmd's build methods).
4) Execute the command on the smart card by calling the appropriate ISCard
interface method.
5) Evaluate the returned response.
6) Repeat the procedure as needed.
7) Release the ISCardCmd interface and others as needed.
Author:
Doug Barlow (dbarlow) 6/24/1999
Notes:
?Notes?
--*/
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include "stdafx.h"
#include "scardssp.h"
#include "ByteBuffer.h"
#include "SCardCmd.h"
#include "Conversion.h"
/////////////////////////////////////////////////////////////////////////////
// CSCardCmd
/*++
CSCardCmd::get_Apdu:
The get_Apdu method retrieves the raw APDU.
Arguments:
ppApdu [out, retval] Pointer to the byte buffer mapped through an IStream
that contains the APDU message on return.
Return Value:
The return value is an HRESULT. A value of S_OK indicates the call was
successful.
Remarks:
To copy the APDU from an IByteBuffer (IStream) object into the APDU
wrapped in this interface object, call put_Apdu.
To determine the length of the APDU, call get_ApduLength.
Author:
Doug Barlow (dbarlow) 6/24/1999
--*/
#undef __SUBROUTINE__
#define __SUBROUTINE__ TEXT("CSCardCmd::get_Apdu")
STDMETHODIMP
CSCardCmd::get_Apdu(
/* [retval][out] */ LPBYTEBUFFER __RPC_FAR *ppApdu)
{
HRESULT hReturn = S_OK;
CByteBuffer *pMyBuffer = NULL;
try
{
CBuffer bfApdu(m_bfRequestData.Length() + 4 + 3 + 3);
if (NULL == *ppApdu)
{
*ppApdu = pMyBuffer = NewByteBuffer();
if (NULL == pMyBuffer)
throw (HRESULT)E_OUTOFMEMORY;
}
ConstructRequest(
m_bCla,
m_bIns,
m_bP1,
m_bP2,
m_bfRequestData,
m_wLe,
m_dwFlags,
bfApdu);
BufferToByteBuffer(bfApdu, ppApdu);
pMyBuffer = NULL;
}
catch (HRESULT hError)
{
hReturn = hError;
}
catch (...)
{
hReturn = E_INVALIDARG;
}
if (NULL != pMyBuffer)
{
pMyBuffer->Release();
*ppApdu = NULL;
}
return hReturn;
}
/*++
CSCardCmd::put_Apdu:
The put_Apdu method copies the APDU from the IByteBuffer (IStream) object
into the APDU wrapped in this interface object.
Arguments:
pApdu [in] Pointer to the ISO 7816-4 APDU to be copied in.
Return Value:
The return value is an HRESULT. A value of S_OK indicates the call was
successful.
Remarks:
To retrieve the raw APDU from the byte buffer mapped through an IStream
that contains the APDU message, call get_Apdu.
Author:
Doug Barlow (dbarlow) 6/24/1999
--*/
#undef __SUBROUTINE__
#define __SUBROUTINE__ TEXT("CSCardCmd::put_Apdu")
STDMETHODIMP
CSCardCmd::put_Apdu(
/* [in] */ LPBYTEBUFFER pApdu)
{
HRESULT hReturn = S_OK;
try
{
CBuffer bfApdu;
LPCBYTE pbData;
WORD wLc;
ByteBufferToBuffer(pApdu, bfApdu);
ParseRequest(
bfApdu.Access(),
bfApdu.Length(),
&m_bCla,
&m_bIns,
&m_bP1,
&m_bP2,
&pbData,
&wLc,
&m_wLe,
&m_dwFlags);
m_bfRequestData.Set(pbData, wLc);
}
catch (HRESULT hError)
{
hReturn = hError;
}
catch (...)
{
hReturn = E_INVALIDARG;
}
return hReturn;
}
/*++
CSCardCmd::get_ApduLength:
The get_ApduLength method determines the length (in bytes) of the APDU.
Arguments:
plSize [out, retval] Pointer to the length of the APDU.
Return Value:
The return value is an HRESULT. A value of S_OK indicates the call was
successful.
Remarks:
To retrieve the raw APDU from the byte buffer mapped through an IStream
that contains the APDU message, call get_Apdu.
Author:
Doug Barlow (dbarlow) 6/24/1999
--*/
#undef __SUBROUTINE__
#define __SUBROUTINE__ TEXT("CSCardCmd::get_ApduLength")
STDMETHODIMP
CSCardCmd::get_ApduLength(
/* [retval][out] */ LONG __RPC_FAR *plSize)
{
HRESULT hReturn = S_OK;
try
{
CBuffer bfApdu;
ConstructRequest(
m_bCla,
m_bIns,
m_bP1,
m_bP2,
m_bfRequestData,
m_wLe,
m_dwFlags,
bfApdu);
*plSize = (LONG)bfApdu.Length();
}
catch (HRESULT hError)
{
hReturn = hError;
}
catch (...)
{
hReturn = E_INVALIDARG;
}
return hReturn;
}
/*++
CSCardCmd::get_ApduReply:
The get_ApduReply retrieves the reply APDU, placing it in a specific byte
buffer. The reply may be NULL if no transaction has been performed on the
command APDU.
Arguments:
ppReplyApdu [out, retval] Pointer to the byte buffer (mapped through an
IStream) that contains the APDU reply message on return.
Return Value:
The return value is an HRESULT. A value of S_OK indicates the call was
successful.
Remarks:
Author:
Doug Barlow (dbarlow) 6/24/1999
--*/
#undef __SUBROUTINE__
#define __SUBROUTINE__ TEXT("CSCardCmd::get_ApduReply")
STDMETHODIMP
CSCardCmd::get_ApduReply(
/* [retval][out] */ LPBYTEBUFFER __RPC_FAR *ppReplyApdu)
{
HRESULT hReturn = S_OK;
LPBYTEBUFFER pMyBuffer = NULL;
try
{
if (NULL == *ppReplyApdu)
{
*ppReplyApdu = pMyBuffer = NewByteBuffer();
if (NULL == pMyBuffer)
throw (HRESULT)E_OUTOFMEMORY;
}
BufferToByteBuffer(m_bfResponseApdu, ppReplyApdu);
pMyBuffer = NULL;
}
catch (HRESULT hError)
{
hReturn = hError;
}
catch (...)
{
hReturn = E_INVALIDARG;
}
if (NULL != pMyBuffer)
{
pMyBuffer->Release();
*ppReplyApdu = NULL;
}
return hReturn;
}
/*++
CSCardCmd::put_ApduReply:
The put_ApduReply method sets a new reply APDU.
Arguments:
pReplyApdu [in] Pointer to the byte buffer (mapped through an IStream) that
contains the replay APDU message on return.
Return Value:
The return value is an HRESULT. A value of S_OK indicates the call was
successful.
Remarks:
Author:
Doug Barlow (dbarlow) 6/24/1999
--*/
#undef __SUBROUTINE__
#define __SUBROUTINE__ TEXT("CSCardCmd::put_ApduReply")
STDMETHODIMP
CSCardCmd::put_ApduReply(
/* [in] */ LPBYTEBUFFER pReplyApdu)
{
HRESULT hReturn = S_OK;
try
{
ByteBufferToBuffer(pReplyApdu, m_bfResponseApdu);
}
catch (HRESULT hError)
{
hReturn = hError;
}
catch (...)
{
hReturn = E_INVALIDARG;
}
return hReturn;
}
/*++
CSCardCmd::get_ApduReplyLength:
The get_ApduReplyLength method determines the length (in bytes) of the
reply APDU.
Arguments:
plSize [out, retval] Pointer to the size of the reply APDU message.
Return Value:
The return value is an HRESULT. A value of S_OK indicates the call was
successful.
Remarks:
Author:
Doug Barlow (dbarlow) 6/24/1999
--*/
#undef __SUBROUTINE__
#define __SUBROUTINE__ TEXT("CSCardCmd::get_ApduReplyLength")
STDMETHODIMP
CSCardCmd::get_ApduReplyLength(
/* [retval][out] */ LONG __RPC_FAR *plSize)
{
HRESULT hReturn = S_OK;
try
{
*plSize = (LONG)m_bfResponseApdu.Length();
}
catch (...)
{
hReturn = E_INVALIDARG;
}
return hReturn;
}
STDMETHODIMP
CSCardCmd::put_ApduReplyLength(
/* [in] */ LONG lSize)
{
HRESULT hReturn = S_OK;
try
{
m_bfResponseApdu.Resize((DWORD)lSize, TRUE);
}
catch (...)
{
hReturn = E_INVALIDARG;
}
return hReturn;
}
/*++
CSCardCmd::get_ClassId:
The get_ClassId method retrieves the class identifier from the APDU.
Arguments:
pbyClass [out, retval] Pointer to the byte that represents the class
identifier.
Return Value:
The return value is an HRESULT. A value of S_OK indicates the call was
successful.
Remarks:
Author:
Doug Barlow (dbarlow) 6/24/1999
--*/
#undef __SUBROUTINE__
#define __SUBROUTINE__ TEXT("CSCardCmd::get_ClassId")
STDMETHODIMP
CSCardCmd::get_ClassId(
/* [retval][out] */ BYTE __RPC_FAR *pbyClass)
{
HRESULT hReturn = S_OK;
try
{
*pbyClass = m_bCla;
}
catch (...)
{
hReturn = E_INVALIDARG;
}
return hReturn;
}
/*++
CSCardCmd::put_ClassId:
The put_ClassId method sets a new class identifier in the APDU.
Arguments:
byClass [in, defaultvalue(0)] The byte that represents the class identifier.
Return Value:
The return value is an HRESULT. A value of S_OK indicates the call was
successful.
Remarks:
Author:
Doug Barlow (dbarlow) 6/24/1999
--*/
#undef __SUBROUTINE__
#define __SUBROUTINE__ TEXT("CSCardCmd::put_ClassId")
STDMETHODIMP
CSCardCmd::put_ClassId(
/* [defaultvalue][in] */ BYTE byClass)
{
HRESULT hReturn = S_OK;
try
{
m_bCla = byClass;
}
catch (...)
{
hReturn = E_INVALIDARG;
}
return hReturn;
}
/*++
CSCardCmd::get_Data:
The get_Data method retrieves the data field from the APDU, placing it in a
byte buffer object.
Arguments:
ppData [out, retval] Pointer to the byte buffer object (IStream) that holds
the APDU's data field on return.
Return Value:
The return value is an HRESULT. A value of S_OK indicates the call was
successful.
Remarks:
Author:
Doug Barlow (dbarlow) 6/24/1999
--*/
#undef __SUBROUTINE__
#define __SUBROUTINE__ TEXT("CSCardCmd::get_Data")
STDMETHODIMP
CSCardCmd::get_Data(
/* [retval][out] */ LPBYTEBUFFER __RPC_FAR *ppData)
{
HRESULT hReturn = S_OK;
CByteBuffer *pMyBuffer = NULL;
try
{
if (NULL == *ppData)
{
*ppData = pMyBuffer = NewByteBuffer();
if (NULL == pMyBuffer)
throw (HRESULT)E_OUTOFMEMORY;
}
BufferToByteBuffer(m_bfRequestData, ppData);
pMyBuffer = NULL;
}
catch (HRESULT hError)
{
hReturn = hError;
}
catch (...)
{
hReturn = E_INVALIDARG;
}
if (NULL != pMyBuffer)
{
pMyBuffer->Release();
*ppData = NULL;
}
return hReturn;
}
/*++
CSCardCmd::put_Data:
The put_Data method sets the data field in the APDU.
Arguments:
pData [in] Pointer to the byte buffer object (IStream) to be copied into
the APDU's data field.
Return Value:
The return value is an HRESULT. A value of S_OK indicates the call was
successful.
Remarks:
Author:
Doug Barlow (dbarlow) 6/24/1999
--*/
#undef __SUBROUTINE__
#define __SUBROUTINE__ TEXT("CSCardCmd::put_Data")
STDMETHODIMP
CSCardCmd::put_Data(
/* [in] */ LPBYTEBUFFER pData)
{
HRESULT hReturn = S_OK;
try
{
ByteBufferToBuffer(pData, m_bfRequestData);
}
catch (HRESULT hError)
{
hReturn = hError;
}
catch (...)
{
hReturn = E_INVALIDARG;
}
return hReturn;
}
/*++
CSCardCmd::get_InstructionId:
The get_InstructionId method retrieves the instruction identifier byte from
the APDU.
Arguments:
pbyIns [out, retval] Pointer to the byte that is the instruction ID from
the APDU on return.
Return Value:
The return value is an HRESULT. A value of S_OK indicates the call was
successful.
Remarks:
Author:
Doug Barlow (dbarlow) 6/24/1999
--*/
#undef __SUBROUTINE__
#define __SUBROUTINE__ TEXT("CSCardCmd::get_InstructionId")
STDMETHODIMP
CSCardCmd::get_InstructionId(
/* [retval][out] */ BYTE __RPC_FAR *pbyIns)
{
HRESULT hReturn = S_OK;
try
{
*pbyIns = m_bIns;
}
catch (...)
{
hReturn = E_INVALIDARG;
}
return hReturn;
}
/*++
CSCardCmd::put_InstructionId:
The put_InstructionId sets the given instruction identifier in the APDU.
Arguments:
byIns [in] The byte that is the instruction identifier.
Return Value:
The return value is an HRESULT. A value of S_OK indicates the call was
successful.
Remarks:
Author:
Doug Barlow (dbarlow) 6/24/1999
--*/
#undef __SUBROUTINE__
#define __SUBROUTINE__ TEXT("CSCardCmd::put_InstructionId")
STDMETHODIMP
CSCardCmd::put_InstructionId(
/* [in] */ BYTE byIns)
{
HRESULT hReturn = S_OK;
try
{
m_bIns = byIns;
}
catch (...)
{
hReturn = E_INVALIDARG;
}
return hReturn;
}
STDMETHODIMP
CSCardCmd::get_LeField(
/* [retval][out] */ LONG __RPC_FAR *plSize)
{
HRESULT hReturn = S_OK;
try
{
*plSize = m_wLe;
}
catch (...)
{
hReturn = E_INVALIDARG;
}
return hReturn;
}
/*++
CSCardCmd::get_P1:
The get_P1 method retrieves the first parameter (P1) byte from the APDU.
Arguments:
pbyP1 [out, retval] Pointer to the P1 byte in the APDU on return.
Return Value:
The return value is an HRESULT. A value of S_OK indicates the call was
successful.
Remarks:
Author:
Doug Barlow (dbarlow) 6/24/1999
--*/
#undef __SUBROUTINE__
#define __SUBROUTINE__ TEXT("CSCardCmd::get_P1")
STDMETHODIMP
CSCardCmd::get_P1(
/* [retval][out] */ BYTE __RPC_FAR *pbyP1)
{
HRESULT hReturn = S_OK;
try
{
*pbyP1 = m_bP1;
}
catch (...)
{
hReturn = E_INVALIDARG;
}
return hReturn;
}
/*++
CSCardCmd::put_P1:
The put_P1 method sets the first parameter (P1) byte of the APDU.
Arguments:
byP1 [in] The byte that is the P1 field.
Return Value:
The return value is an HRESULT. A value of S_OK indicates the call was
successful.
Remarks:
Author:
Doug Barlow (dbarlow) 6/24/1999
--*/
#undef __SUBROUTINE__
#define __SUBROUTINE__ TEXT("CSCardCmd::put_P1")
STDMETHODIMP
CSCardCmd::put_P1(
/* [in] */ BYTE byP1)
{
HRESULT hReturn = S_OK;
try
{
m_bP1 = byP1;
}
catch (...)
{
hReturn = E_INVALIDARG;
}
return hReturn;
}
/*++
CSCardCmd::get_P2:
The get_P2 method retrieves the second parameter (P2) byte from the APDU
Arguments:
pbyP2 [out, retval] Pointer to the byte that is the P2 from the APDU on
return.
Return Value:
The return value is an HRESULT. A value of S_OK indicates the call was
successful.
Remarks:
Author:
Doug Barlow (dbarlow) 6/24/1999
--*/
#undef __SUBROUTINE__
#define __SUBROUTINE__ TEXT("CSCardCmd::get_P2")
STDMETHODIMP
CSCardCmd::get_P2(
/* [retval][out] */ BYTE __RPC_FAR *pbyP2)
{
HRESULT hReturn = S_OK;
try
{
*pbyP2 = m_bP2;
}
catch (...)
{
hReturn = E_INVALIDARG;
}
return hReturn;
}
/*++
CSCardCmd::put_P2:
The put_P2 method sets the second parameter (P2) byte in the APDU.
Arguments:
byP2 [in] The byte that is the P2 field.
Return Value:
The return value is an HRESULT. A value of S_OK indicates the call was
successful.
Remarks:
Author:
Doug Barlow (dbarlow) 6/24/1999
--*/
#undef __SUBROUTINE__
#define __SUBROUTINE__ TEXT("CSCardCmd::put_P2")
STDMETHODIMP
CSCardCmd::put_P2(
/* [in] */ BYTE byP2)
{
HRESULT hReturn = S_OK;
try
{
m_bP2 = byP2;
}
catch (...)
{
hReturn = E_INVALIDARG;
}
return hReturn;
}
/*++
CSCardCmd::get_P3:
The get_P3 method retrieves the third parameter (P3) byte from the APDU.
This read-only byte value represents the size of the data portion of the
APDU.
Arguments:
pbyP3 [out, retval] Pointer to the byte that is the P3 from the APDU on
return.
Return Value:
The return value is an HRESULT. A value of S_OK indicates the call was
successful.
Remarks:
Author:
Doug Barlow (dbarlow) 6/24/1999
--*/
#undef __SUBROUTINE__
#define __SUBROUTINE__ TEXT("CSCardCmd::get_P3")
STDMETHODIMP
CSCardCmd::get_P3(
/* [retval][out] */ BYTE __RPC_FAR *pbyP3)
{
HRESULT hReturn = S_OK;
try
{
*pbyP3 = (BYTE)m_bfRequestData.Length();
}
catch (...)
{
hReturn = E_INVALIDARG;
}
return hReturn;
}
/*++
CSCardCmd::get_ReplyStatus:
The get_ReplyStatus method retrieves the reply APDU's message status word.
Arguments:
pwStatus [out, retval] Pointer to the word that is the status on return.
Return Value:
The return value is an HRESULT. A value of S_OK indicates the call was
successful.
Remarks:
Author:
Doug Barlow (dbarlow) 6/24/1999
--*/
#undef __SUBROUTINE__
#define __SUBROUTINE__ TEXT("CSCardCmd::get_ReplyStatus")
STDMETHODIMP
CSCardCmd::get_ReplyStatus(
/* [retval][out] */ LPWORD pwStatus)
{
HRESULT hReturn = S_OK;
try
{
DWORD dwLen = m_bfResponseApdu.Length();
if (2 <= dwLen)
*pwStatus = NetToLocal(m_bfResponseApdu.Access(dwLen - 2));
else
*pwStatus = 0;
}
catch (...)
{
hReturn = E_INVALIDARG;
}
return hReturn;
}
/*++
CSCardCmd::put_ReplyStatus:
The put_ReplyStatus sets a new reply APDU's message status word.
Arguments:
wStatus [in] The word that is the status.
Return Value:
The return value is an HRESULT. A value of S_OK indicates the call was
successful.
Remarks:
Author:
Doug Barlow (dbarlow) 6/24/1999
--*/
#undef __SUBROUTINE__
#define __SUBROUTINE__ TEXT("CSCardCmd::put_ReplyStatus")
STDMETHODIMP
CSCardCmd::put_ReplyStatus(
/* [in] */ WORD wStatus)
{
HRESULT hReturn = S_OK;
try
{
DWORD dwLen = m_bfResponseApdu.Length();
if (2 <= dwLen)
CopyMemory(m_bfResponseApdu.Access(dwLen - 2), &wStatus, 2);
else
m_bfResponseApdu.Set((LPCBYTE)&wStatus, 2);
}
catch (...)
{
hReturn = E_INVALIDARG;
}
return hReturn;
}
/*++
CSCardCmd::get_ReplyStatusSW1:
The get_ReplyStatusSW1 method retrieves the reply APDU's SW1 status byte.
Arguments:
pbySW1 [out, retval] Pointer to the byte that contains the value of the SW1
byte on return.
Return Value:
The return value is an HRESULT. A value of S_OK indicates the call was
successful.
Remarks:
Author:
Doug Barlow (dbarlow) 6/24/1999
--*/
#undef __SUBROUTINE__
#define __SUBROUTINE__ TEXT("CSCardCmd::get_ReplyStatusSW1")
STDMETHODIMP
CSCardCmd::get_ReplyStatusSW1(
/* [retval][out] */ BYTE __RPC_FAR *pbySW1)
{
HRESULT hReturn = S_OK;
try
{
DWORD dwLen = m_bfResponseApdu.Length();
if (2 <= dwLen)
*pbySW1 = *m_bfResponseApdu.Access(dwLen - 2);
else
*pbySW1 = 0;
}
catch (HRESULT hError)
{
hReturn = hError;
}
catch (...)
{
hReturn = E_INVALIDARG;
}
return hReturn;
}
/*++
CSCardCmd::get_ReplyStatusSW2:
The get_ReplyStatusSW2 method retrieves the reply APDU's SW2 status byte.
Arguments:
pbySW2 [out, retval] Pointer to the byte that contains the value of the SW2
byte on return.
Return Value:
The return value is an HRESULT. A value of S_OK indicates the call was
successful.
Remarks:
Author:
Doug Barlow (dbarlow) 6/24/1999
--*/
#undef __SUBROUTINE__
#define __SUBROUTINE__ TEXT("CSCardCmd::get_ReplyStatusSW2")
STDMETHODIMP
CSCardCmd::get_ReplyStatusSW2(
/* [retval][out] */ BYTE __RPC_FAR *pbySW2)
{
HRESULT hReturn = S_OK;
try
{
DWORD dwLen = m_bfResponseApdu.Length();
if (2 <= dwLen)
*pbySW2 = *m_bfResponseApdu.Access(dwLen - 1);
else
*pbySW2 = 0;
}
catch (...)
{
hReturn = E_INVALIDARG;
}
return hReturn;
}
#undef __SUBROUTINE__
#define __SUBROUTINE__ TEXT("CSCardCmd::get_Type")
STDMETHODIMP
CSCardCmd::get_Type(
/* [retval][out] */ ISO_APDU_TYPE __RPC_FAR *pType)
{
HRESULT hReturn = S_OK;
try
{
// ?todo?
breakpoint;
hReturn = E_NOTIMPL;
}
catch (HRESULT hError)
{
hReturn = hError;
}
catch (...)
{
hReturn = E_INVALIDARG;
}
return hReturn;
}
STDMETHODIMP
CSCardCmd::get_Nad(
/* [retval][out] */ BYTE __RPC_FAR *pbNad)
{
HRESULT hReturn = S_OK;
try
{
if (0 != (m_dwFlags & APDU_REQNAD_VALID))
*pbNad = m_bRequestNad;
else
hReturn = E_ACCESSDENIED;
}
catch (...)
{
hReturn = E_INVALIDARG;
}
return hReturn;
}
STDMETHODIMP
CSCardCmd::put_Nad(
/* [in] */ BYTE bNad)
{
HRESULT hReturn = S_OK;
try
{
m_bRequestNad = bNad;
m_dwFlags |= APDU_REQNAD_VALID;
}
catch (...)
{
hReturn = E_INVALIDARG;
}
return hReturn;
}
STDMETHODIMP
CSCardCmd::get_ReplyNad(
/* [retval][out] */ BYTE __RPC_FAR *pbNad)
{
HRESULT hReturn = S_OK;
try
{
if (0 != (APDU_RSPNAD_VALID & m_dwFlags))
*pbNad = m_bResponseNad;
else
hReturn = E_ACCESSDENIED;
}
catch (...)
{
hReturn = E_INVALIDARG;
}
return hReturn;
}
STDMETHODIMP
CSCardCmd::put_ReplyNad(
/* [in] */ BYTE bNad)
{
HRESULT hReturn = S_OK;
try
{
m_bResponseNad = bNad;
m_dwFlags |= APDU_RSPNAD_VALID;
}
catch (...)
{
hReturn = E_INVALIDARG;
}
return hReturn;
}
/*++
CSCardCmd::get_AlternateClassId:
The get_AlternateClassId method retrieves the alternate class identifier
from the APDU. The Alternate Class Id is used for automatically generated
GetResponse and Envelope commands when T=0 is used.
Arguments:
pbyClass [out, retval] Pointer to the byte that represents the alternate
class identifier.
Return Value:
The return value is an HRESULT. A value of S_OK indicates the call was
successful.
Remarks:
Author:
Doug Barlow (dbarlow) 6/24/1999
--*/
#undef __SUBROUTINE__
#define __SUBROUTINE__ TEXT("CSCardCmd::get_AlternateClassId")
STDMETHODIMP
CSCardCmd::get_AlternateClassId(
/* [retval][out] */ BYTE __RPC_FAR *pbyClass)
{
HRESULT hReturn = S_OK;
try
{
if (0 != (m_dwFlags & APDU_ALTCLA_VALID))
*pbyClass = m_bAltCla;
else
hReturn = E_ACCESSDENIED;
}
catch (...)
{
hReturn = E_INVALIDARG;
}
return hReturn;
}
/*++
CSCardCmd::put_AlternateClassId:
The put_AlternateClassId method sets a new alternate class identifier in
the APDU. The Alternate Class Id is used for automatically generated
GetResponse and Envelope commands when T=0 is used. If no alternate class
identifier is set, then the CLA of the original command is used.
Arguments:
byClass [in, defaultvalue(0)] The byte that represents the alternate class
identifier.
Return Value:
The return value is an HRESULT. A value of S_OK indicates the call was
successful.
Remarks:
Author:
Doug Barlow (dbarlow) 6/24/1999
--*/
#undef __SUBROUTINE__
#define __SUBROUTINE__ TEXT("CSCardCmd::put_AlternateClassId")
STDMETHODIMP
CSCardCmd::put_AlternateClassId(
/* [defaultvalue][in] */ BYTE byClass)
{
HRESULT hReturn = S_OK;
try
{
m_bAltCla = byClass;
m_dwFlags |= APDU_ALTCLA_VALID;
}
catch (...)
{
hReturn = E_INVALIDARG;
}
return hReturn;
}
/*++
CSCardCmd::BuildCmd:
The BuildCmd method constructs a valid command APDU for transmission to a
smart card.
Arguments:
byClassId [in] Command class identifier.
byInsId [in] Command instruction identifier.
byP1 [in, defaultvalue(0)] Command's first parameter.
byP2 [in, defaultvalue(0)] Command's second parameter.
pbyData [in, defaultvalue(NULL)] Pointer to the data portion of the
command.
p1Le [in, defaultvalue(NULL)] Pointer to a LONG integer containing the
expected length of the returned data.
Return Value:
The return value is an HRESULT. A value of S_OK indicates the call was
successful.
Remarks:
Author:
Doug Barlow (dbarlow) 6/24/1999
--*/
#undef __SUBROUTINE__
#define __SUBROUTINE__ TEXT("CSCardCmd::BuildCmd")
STDMETHODIMP
CSCardCmd::BuildCmd(
/* [in] */ BYTE byClassId,
/* [in] */ BYTE byInsId,
/* [defaultvalue][in] */ BYTE byP1,
/* [defaultvalue][in] */ BYTE byP2,
/* [defaultvalue][in] */ LPBYTEBUFFER pbyData,
/* [defaultvalue][in] */ LONG __RPC_FAR *plLe)
{
HRESULT hReturn = S_OK;
try
{
ByteBufferToBuffer(pbyData, m_bfRequestData);
m_bCla = byClassId;
m_bIns = byInsId;
m_bP1 = byP1;
m_bP2 = byP2;
m_dwFlags = 0;
if (NULL != plLe)
{
switch (*plLe)
{
case 0x10000:
m_dwFlags |= APDU_EXTENDED_LENGTH;
// Fall through intentionally
case 0x100:
case 0:
m_dwFlags |= APDU_MAXIMUM_LE;
m_wLe = 0;
break;
default:
if (0x10000 < *plLe)
throw (HRESULT)E_INVALIDARG;
if (0x100 < *plLe)
m_dwFlags |= APDU_EXTENDED_LENGTH;
m_wLe = (WORD)(*plLe);
}
}
}
catch (HRESULT hError)
{
hReturn = hError;
}
catch (...)
{
hReturn = E_INVALIDARG;
}
return hReturn;
}
/*++
CSCardCmd::Clear:
The Clear method clears the APDU and reply APDU message buffers.
Arguments:
None
Return Value:
The return value is an HRESULT. A value of S_OK indicates the call was
successful.
Remarks:
Author:
Doug Barlow (dbarlow) 6/24/1999
--*/
#undef __SUBROUTINE__
#define __SUBROUTINE__ TEXT("CSCardCmd::Clear")
STDMETHODIMP
CSCardCmd::Clear(
void)
{
HRESULT hReturn = S_OK;
try
{
m_bfRequestData.Reset();
m_bfResponseApdu.Reset();
}
catch (...)
{
hReturn = E_INVALIDARG;
}
return hReturn;
}
/*++
CSCardCmd::Encapsulate:
The Encapsulate method encapsulates the given command APDU into another
command APDU for transmission to a smart card.
Arguments:
pApdu [in] Pointer to the APDU to be encapsulated.
ApduType [in] Specifies the ISO 7816-4 case for T0 transmissions. Possible
values are:
ISO_CASE_1
ISO_CASE_2
ISO_CASE_3
ISO_CASE_4
Return Value:
The return value is an HRESULT. A value of S_OK indicates the call was
successful.
Remarks:
Author:
Doug Barlow (dbarlow) 6/24/1999
--*/
#undef __SUBROUTINE__
#define __SUBROUTINE__ TEXT("CSCardCmd::Encapsulate")
STDMETHODIMP
CSCardCmd::Encapsulate(
/* [in] */ LPBYTEBUFFER pApdu,
/* [in] */ ISO_APDU_TYPE ApduType)
{
HRESULT hReturn = S_OK;
try
{
WORD wLe;
DWORD dwFlags;
//
// Get the APDU to be encapsulated.
//
ByteBufferToBuffer(pApdu, m_bfRequestData);
//
// Parse it.
//
ParseRequest(
m_bfRequestData.Access(),
m_bfRequestData.Length(),
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
&wLe,
&dwFlags);
m_bIns = 0xc2;
m_bP1 = 0x00;
m_bP2 = 0x00;
m_wLe = wLe;
m_dwFlags = dwFlags;
// ?todo? -- support ApduType
}
catch (HRESULT hError)
{
hReturn = hError;
}
catch (...)
{
hReturn = E_INVALIDARG;
}
return hReturn;
}