// SCardMan.cpp : Implementation of CSCardManage
//////////////////////////////////////////////////////////////////////////
//
// Includes
//
#include "stdafx.h"
#include "SCardCom.h"
#include "SCardMan.h"
// Include the SSP GUIDS
#include <sspguid.h>
///////////////////////////////////////////////////////////////////////////
// Macros
//
#ifdef _DEBUG
#define TRACE_STR(name,sz) \
TRACE(_T("SMB_SSP.DLL: CSCardManage::%s: %s\n"), name, sz)
#define TRACE_CODE(name,code) \
TRACE(_T("SMB_SSP.DLL: CSCardManage::%s: error = 0x%x\n"), name, code)
#define TRACE_CATCH(name,code) TRACE_CODE(name,code)
#define TRACE_CATCH_UNKNOWN(name) TRACE_STR(name,_T("An unidentified exception has occurred!"))
#else
#define TRACE_STR(name,sz) ((void)0)
#define TRACE_CODE(name,code) ((void)0)
#define TRACE_CATCH(name,code) ((void)0)
#define TRACE_CATCH_UNKNOWN(name) ((void)0)
#endif // _DEBUG
/////////////////////////////////////////////////////////////////////////////
// CSCardManage
/*++
FinalConstruct:
This routine defines a final constructor that is called after the constructor
for the template class is called.
Arguments:
None
Return Value:
A HRESULT value indicating the status of the requested action.
Return Meaning
====== =======
S_OK Operation completed successfully.
S_FALSE Unknown error occurred.
E_OUTOFMEMORY There is not enough memory in this process to
satisfy the request.
E_FAIL Unspecified error.
E_INVALIDARG One or more arguments are invalid.
E_UNEXPECTED Unexpected event occurred in this function.
Author:
--*/
HRESULT CSCardManage::FinalConstruct()
{
// Locals.
HRESULT hresult = S_OK;
try {
// Check Params, etc
///////////////////////////////////////////////////////////////////////////
//
// Create an instance of all the low-level COM objects-interfaces
//
//
hresult = CoCreateInstance( CLSID_CSCard,
NULL,
CLSCTX_LOCAL,
IID_ISCard,
(LPVOID*) &m_pISCard);
if (FAILED(hresult))
throw (hresult);
hresult = CoCreateInstance( CLSID_CSCardTypeConv,
NULL,
CLSCTX_LOCAL,
IID_ISCardTypeConv,
(LPVOID*) &m_pISCardTypeConv);
if (FAILED(hresult))
throw (hresult);
hresult = CoCreateInstance( CLSID_CSCardISO7816,
NULL,
CLSCTX_LOCAL,
IID_ISCardISO7816,
(LPVOID*) &m_pISCardISO7816);
if (FAILED(hresult))
throw (hresult);
// If Required...
hresult = CoCreateInstance( CLSID_CSCardDatabase,
NULL,
CLSCTX_LOCAL,
IID_ISCardDatabase,
(LPVOID*) &m_pISCardDatabase);
if (FAILED(hresult))
throw (hresult);
hresult = CoCreateInstance( CLSID_CSCardLocate,
NULL,
CLSCTX_LOCAL,
IID_ISCardLocate,
(LPVOID*) &m_pISCardLocate);
if (FAILED(hresult))
throw (hresult);
}
catch (HRESULT hr) {
hresult = hr;
TRACE_CATCH(_T("FinalConstruct"),hr);
}
catch (...) {
hresult = E_UNEXPECTED;
TRACE_CATCH_UNKNOWN(_T("FinalConstruct"));
}
return (hresult);
}
/*++
FinalRelease:
This routine defines a final release.
Arguments:
None
Return Value:
A HRESULT value indicating the status of the requested action.
Return Meaning
====== =======
S_OK Operation completed successfully.
S_FALSE Unknown error occurred.
E_OUTOFMEMORY There is not enough memory in this process to
satisfy the request.
E_FAIL Unspecified error.
E_INVALIDARG One or more arguments are invalid.
E_UNEXPECTED Unexpected event occurred in this function.
Author:
--*/
HRESULT CSCardManage::FinalRelease()
{
// Locals.
HRESULT hresult = S_OK;
try {
// Release the Interfaces
m_pISCard->Release();
m_pISCardISO7816->Release();
m_pISCardTypeConv->Release();
// If required...
m_pISCardDatabase->Release();
m_pISCardLocate->Release();
}
catch (...) {
hresult = (HRESULT) E_UNEXPECTED;
TRACE_CATCH_UNKNOWN(_T("AttachByIFD"));
}
return (hresult);
}
/*++
CreateCmdObject:
This routine creates an instance of the ISCardCmd object
Arguments:
ppCmd - pointer to an ISCardCmd pointer
Return Value:
A HRESULT value indicating the status of the requested action.
Return Meaning
====== =======
S_OK Operation completed successfully.
S_FALSE Unknown error occurred.
E_OUTOFMEMORY There is not enough memory in this process to
satisfy the request.
E_FAIL Unspecified error.
E_INVALIDARG One or more arguments are invalid.
E_UNEXPECTED Unexpected event occurred in this function.
Author:
--*/
HRESULT CSCardManage::CreateCmdObject(LPSCARDCMD *ppCmd)
{
// Locals
HRESULT hresult = S_OK;
LPSCARDCMD pObj = NULL;
try {
// Check Params, etc...
if (ppCmd==NULL)
throw ( (HRESULT) E_INVALIDARG );
// Create the object
hresult = CoCreateInstance( CLSID_CSCardCmd,
NULL,
CLSCTX_LOCAL,
IID_ISCardCmd,
(LPVOID*) &pObj);
if (FAILED(hresult))
throw (hresult);
ASSERT( (pObj) != NULL );
// Package for return
(*ppCmd) = pObj;
}
catch (HRESULT hr) {
hresult=hr;
TRACE_CATCH(_T("CreateCmdObject"), hr);
}
catch (...) {
hresult = (HRESULT) E_UNEXPECTED;
TRACE_CATCH_UNKNOWN(_T("CreateCmdObject"));
}
return hresult;
}
/////////////////////////////////////////////////////////////////////////////
//
// ISCardManage Methods
//
/*++
CSCardManage::AttachByHandle:
Allows an application to create a communication to an ICC using
a handle returned by the Resource Manager
Arguments:
hICC - handle to the ICC
Return Value:
A HRESULT value indicating the status of the requested action.
Return Meaning
====== =======
S_OK Operation completed successfully.
S_FALSE Unknown error occurred.
E_OUTOFMEMORY There is not enough memory in this process to
satisfy the request.
E_FAIL Unspecified error.
E_INVALIDARG One or more arguments are invalid.
E_UNEXPECTED Unexpected event occurred in this function.
Author:
--*/
STDMETHODIMP CSCardManage::AttachByHandle(
HSCARD hICC)
{
//locals
HRESULT hresult = S_OK;
try {
if (hICC == 0)
throw ( (HRESULT) E_INVALIDARG);
// Make low level COM call
hresult = m_pISCard->AttachByHandle(hICC);
if (FAILED(hresult))
throw (hresult);
}
catch (HRESULT hr) {
hresult = hr;
TRACE_CATCH(_T("AttachByHandle"), hr);
}
catch (...) {
hresult = (HRESULT) E_UNEXPECTED;
TRACE_CATCH_UNKNOWN(_T("AttachByHandle"));
}
return hresult;
}
/*++
CSCardManage::AttachByIFD:
Allows an application to request establishment of a context for
a specific IFD referenced with a friendly name
Arguments:
bstrIFDName - String containing friendly name
Flags - desired access mode
Return Value:
A HRESULT value indicating the status of the requested action.
Return Meaning
====== =======
S_OK Operation completed successfully.
S_FALSE Unknown error occurred.
E_OUTOFMEMORY There is not enough memory in this process to
satisfy the request.
E_FAIL Unspecified error.
E_INVALIDARG One or more arguments are invalid.
E_UNEXPECTED Unexpected event occurred in this function.
Author:
--*/
STDMETHODIMP CSCardManage::AttachByIFD(
BSTR bstrIFDName,
SCARD_SHARE_MODES Flags)
{
//locals
HRESULT hresult = S_OK;
try {
if (bstrIFDName == NULL)
throw ( (HRESULT) E_INVALIDARG);
// make low level COM call...Default to T0 protocol for Cryptoflex
// Note: In this example code we are grabbing the reader for SHAREd
// use. This implies we MUST use ISCard->Lock (SCardBeginTransaction) and
// ISCard->Unlock (SCardEndTransaction) when communicating with the card.
// The begin/end transaction functions should be called in any case.
hresult = m_pISCard->AttachByReader(bstrIFDName, SHARED, T0);
if (FAILED(hresult))
throw (hresult);
}
catch (HRESULT hr) {
hresult = hr;
TRACE_CATCH(_T("AttachByIFD"), hr);
}
catch (...) {
hresult = (HRESULT) E_UNEXPECTED;
TRACE_CATCH_UNKNOWN(_T("AttachByIFD"));
}
return hresult;
}
/*++
CSCardManage::CreateCardAuth:
Creates an instance of the ISCardAuth interface and returns
a pointer to the created interface.
Arguments:
pISCardAuth - pointer to ISCardAuth
Return Value:
A HRESULT value indicating the status of the requested action.
Return Meaning
====== =======
S_OK Operation completed successfully.
S_FALSE Unknown error occurred.
E_OUTOFMEMORY There is not enough memory in this process to
satisfy the request.
E_FAIL Unspecified error.
E_INVALIDARG One or more arguments are invalid.
E_UNEXPECTED Unexpected event occurred in this function.
Author:
--*/
STDMETHODIMP CSCardManage::CreateCardAuth( LPSCARDAUTH* ppISCardAuth )
{
// Locals
HRESULT hresult = S_OK;
LPSCARDAUTH pObj = NULL;
try {
// Check params, etc..
if (ppISCardAuth == NULL)
throw ( (HRESULT) E_INVALIDARG );
// Create an instance of the interface
hresult = CoCreateInstance( CLSID_SCardAuth,
NULL,
CLSCTX_LOCAL,
IID_ISCardAuth,
(LPVOID*) &pObj);
if (FAILED(hresult))
throw (hresult);
// Initialize the Interface/Object
hresult = pObj->Initialize((LONG*) this);
if (FAILED(hresult))
throw (hresult);
// Ok...
(*ppISCardAuth) = pObj;
// We are bumping the reference count on this object so we are sure it will
// remain available. This means each object MUST Release() the count!
AddRef();
}
catch (HRESULT hr) {
hresult = hr;
TRACE_CATCH(_T("CreateCardAuth"),hr);
}
catch (...) {
hresult = (HRESULT) E_UNEXPECTED;
TRACE_CATCH_UNKNOWN(_T("CreateCardAuth"));
}
return hresult;
}
/*++
CSCardManage::CreateFileAccess:
Creates an instance of the ISCardFileAccess interface and returns
a pointer to the created interface.
Arguments:
pISCardFileAccess - pointer to ISCardFileAccess
Return Value:
A HRESULT value indicating the status of the requested action.
Return Meaning
====== =======
S_OK Operation completed successfully.
S_FALSE Unknown error occurred.
E_OUTOFMEMORY There is not enough memory in this process to
satisfy the request.
E_FAIL Unspecified error.
E_INVALIDARG One or more arguments are invalid.
E_UNEXPECTED Unexpected event occurred in this function.
Author:
--*/
STDMETHODIMP CSCardManage::CreateFileAccess( LPSCARDFILEACCESS *ppISCardFileAccess )
{
// Locals
HRESULT hresult = S_OK;
LPSCARDFILEACCESS pObj = NULL;
try {
// Check params, etc..
if (ppISCardFileAccess == NULL)
throw ( (HRESULT) E_INVALIDARG );
// Create an instance of the interface
hresult = CoCreateInstance( CLSID_SCardFileAccess,
NULL,
CLSCTX_LOCAL,
IID_ISCardFileAccess,
(LPVOID*) &pObj);
if (FAILED(hresult))
throw (hresult);
// Initialize the Interface/Object
hresult = pObj->Initialize((LONG*) this);
if (FAILED(hresult))
throw (hresult);
// Ok...
(*ppISCardFileAccess) = pObj;
// We are bumping the reference count on this object so we are sure it will
// remain available. This means each object MUST Release() the count!
AddRef();
}
catch (HRESULT hr) {
hresult = hr;
TRACE_CATCH(_T("CreateFileAccess"),hr);
}
catch (...) {
hresult = (HRESULT) E_UNEXPECTED;
TRACE_CATCH_UNKNOWN(_T("CreateFileAccess"));
}
return hresult;
}
/*++
CSCardManage::CreateInterface
Creates an instance of an interface supported by this ssp.
Arguments:
pISCardFileAccess - pointer to ISCardFileAccess
Return Value:
A HRESULT value indicating the status of the requested action.
Return Meaning
====== =======
S_OK Operation completed successfully.
S_FALSE Unknown error occurred.
E_OUTOFMEMORY There is not enough memory in this process to
satisfy the request.
E_FAIL Unspecified error.
E_INVALIDARG One or more arguments are invalid.
E_UNEXPECTED Unexpected event occurred in this function.
Author:
--*/
STDMETHODIMP CSCardManage::CreateInterface( LPGUID pguidInterface,
BSTR bstrName /*=NULL*/,
LONG *pUserData /*=NULL*/,
LPUNKNOWN *ppInterface)
{
// Locals
HRESULT hresult = E_NOTIMPL;
try {
// Check params, etc..
// Todo::Add code to support the creation of non-standard or
// crypto interfaces
}
catch (HRESULT hr) {
hresult = hr;
TRACE_CATCH(_T("CreateInterface"),hr);
}
catch (...) {
hresult = (HRESULT) E_UNEXPECTED;
TRACE_CATCH_UNKNOWN(_T("CreateInterface"));
}
return hresult;
}
/*++
CSCardManage::CreateCHVerification:
Creates an instance of the ISCardVerify interface and returns
a pointer to the created interface.
Arguments:
pISCardVerify - pointer to ISCardVerify
Return Value:
A HRESULT value indicating the status of the requested action.
Return Meaning
====== =======
S_OK Operation completed successfully.
S_FALSE Unknown error occurred.
E_OUTOFMEMORY There is not enough memory in this process to
satisfy the request.
E_FAIL Unspecified error.
E_INVALIDARG One or more arguments are invalid.
E_UNEXPECTED Unexpected event occurred in this function.
Author:
--*/
STDMETHODIMP CSCardManage::CreateCHVerification( LPSCARDVERIFY *ppISCardVerify )
{
// Locals
HRESULT hresult = S_OK;
LPSCARDVERIFY pObj = NULL;
try {
// Check params, etc..
if (ppISCardVerify == NULL)
throw ( (HRESULT) E_INVALIDARG );
// Create an instance of the interface
hresult = CoCreateInstance( CLSID_SCardVerify,
NULL,
CLSCTX_LOCAL,
IID_ISCardVerify,
(LPVOID*) &pObj);
if (FAILED(hresult))
throw (hresult);
// Initialize the Interface/Object
hresult = pObj->Initialize((LONG*) this);
if (FAILED(hresult))
throw (hresult);
// Ok...
(*ppISCardVerify) = pObj;
// We are bumping the reference count on this object so we are sure it will
// remain available. This means each object MUST Release() the count!
AddRef();
}
catch (HRESULT hr) {
hresult = hr;
TRACE_CATCH(_T("CreateCHVerify"),hr);
}
catch (...) {
hresult = (HRESULT) E_UNEXPECTED;
TRACE_CATCH_UNKNOWN(_T("CreateCHVerify"));
}
return hresult;
}
/*++
CSCardManage::Detach
Releases the attachment to a particular ICC or IFD allocated by
an AttachByxxx method
Arguments:
none
Return Value:
A HRESULT value indicating the status of the requested action.
Return Meaning
====== =======
S_OK Operation completed successfully.
S_FALSE Unknown error occurred.
E_OUTOFMEMORY There is not enough memory in this process to
satisfy the request.
E_FAIL Unspecified error.
E_INVALIDARG One or more arguments are invalid.
E_UNEXPECTED Unexpected event occurred in this function.
Author:
--*/
STDMETHODIMP CSCardManage::Detach()
{
//locals
HRESULT hresult = S_OK;
try {
// Make low-level COM call
hresult = m_pISCard->Detach(LEAVE);
if (FAILED(hresult))
throw (hresult);
}
catch (HRESULT hr) {
hresult = hr;
TRACE_CATCH(_T("Detach"),hr);
}
catch (...) {
hresult = (HRESULT) E_UNEXPECTED;
TRACE_CATCH_UNKNOWN(_T("Detach"));
}
return hresult;
}
/*++
CSCardManage::Locks:
Locks the connected IFD/ICC for exclusive use by this application. Usually
used for executing mutiple/sequence of commands to the card.
Arguments:
none
Return Value:
A HRESULT value indicating the status of the requested action.
Return Meaning
====== =======
S_OK Operation completed successfully.
S_FALSE Unknown error occurred.
E_OUTOFMEMORY There is not enough memory in this process to
satisfy the request.
E_FAIL Unspecified error.
E_INVALIDARG One or more arguments are invalid.
E_UNEXPECTED Unexpected event occurred in this function.
Author:
--*/
STDMETHODIMP CSCardManage::Lock()
{
//locals
HRESULT hresult = S_OK;
try {
// Call low-level COM
hresult = m_pISCard->LockSCard();
if (FAILED(hresult))
throw (hresult);
}
catch (HRESULT hr) {
hresult = hr;
TRACE_CATCH(_T("Lock"), hr);
}
catch (...) {
hresult = E_UNEXPECTED;
TRACE_CATCH_UNKNOWN(_T("Lock"));
}
return hresult;
}
/*++
CSCardManage::Reconnect:
Allows an application to reconnect to an ICC or IFD without having
to issue a Detach then a AttachByxxx method call
Arguments:
none
Return Value:
A HRESULT value indicating the status of the requested action.
Return Meaning
====== =======
S_OK Operation completed successfully.
S_FALSE Unknown error occurred.
E_OUTOFMEMORY There is not enough memory in this process to
satisfy the request.
E_FAIL Unspecified error.
E_INVALIDARG One or more arguments are invalid.
E_UNEXPECTED Unexpected event occurred in this function.
Author:
--*/
STDMETHODIMP CSCardManage::Reconnect()
{
//locals
HRESULT hresult = S_OK;
try {
// Call low-level COM
hresult = m_pISCard->ReAttach(SHARED, LEAVE);
if (FAILED(hresult))
throw (hresult);
}
catch (HRESULT hr) {
hresult = hr;
TRACE_CATCH(_T("Reconnect"), hr);
}
catch (...) {
hresult = E_UNEXPECTED;
TRACE_CATCH_UNKNOWN(_T("Reconnect"));
}
return hresult;
}
/*++
CSCardManage::Status:
Allows an application to get the current status of the ICC/IFD.
Arguments:
pwdStatus - Pointer to DWORD that will contain status
ABSENT
PRESENT
SWALLOWED
POWERED
NEGOTIABLEMODE
SPECIFICMODE
pwdProtocol - point to DWORD that will contain current protocol in use
T0
T1
RAW
Return Value:
A HRESULT value indicating the status of the requested action.
Return Meaning
====== =======
S_OK Operation completed successfully.
S_FALSE Unknown error occurred.
E_OUTOFMEMORY There is not enough memory in this process to
satisfy the request.
E_FAIL Unspecified error.
E_INVALIDARG One or more arguments are invalid.
E_UNEXPECTED Unexpected event occurred in this function.
Author:
--*/
STDMETHODIMP CSCardManage::Status( SCARD_STATES *pStatus,
SCARD_PROTOCOLS *pProtocol)
{
//locals
HRESULT hresult = S_OK;
try {
if ( (pStatus==NULL) || (pProtocol == NULL))
throw ( (HRESULT) E_INVALIDARG );
// Call low-level COM
hresult = m_pISCard->get_Status(pStatus);
if (FAILED(hresult))
throw (hresult);
hresult = m_pISCard->get_Protocol(pProtocol);
if (FAILED(hresult))
throw (hresult);
}
catch (HRESULT hr) {
hresult = hr;
TRACE_CATCH(_T("Status"), hr);
}
catch (...) {
hresult = E_UNEXPECTED;
TRACE_CATCH_UNKNOWN(_T("Status"));
}
return hresult;
}
/*++
CSCardManage::Unlock:
This method releases the connected IFD/ICC from exclusive use.
Arguments:
Disposition - state to leave card in upon release.
LEAVE
RESET
UNPOWER
EJECT
Return Value:
A HRESULT value indicating the status of the requested action.
Return Meaning
====== =======
S_OK Operation completed successfully.
S_FALSE Unknown error occurred.
E_OUTOFMEMORY There is not enough memory in this process to
satisfy the request.
E_FAIL Unspecified error.
E_INVALIDARG One or more arguments are invalid.
E_UNEXPECTED Unexpected event occurred in this function.
Author:
--*/
STDMETHODIMP CSCardManage::Unlock( SCARD_DISPOSITIONS Disposition /*=LEAVE*/)
{
//locals
HRESULT hresult = S_OK;
try {
// Call low-level COM
hresult = m_pISCard->UnlockSCard(Disposition);
if (FAILED(hresult))
throw (hresult);
}
catch (HRESULT hr) {
hresult = hr;
TRACE_CATCH(_T("Unlock"), hr);
}
catch (...) {
hresult = E_UNEXPECTED;
TRACE_CATCH_UNKNOWN(_T("Unlock"));
}
return hresult;
}