|
|
/*
** Proxied Application Program Interface (API) for Windows Card ** */
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include "MarshalPC.h"
#include "carddbg.h"
LONG WINAPI SCWTransmit(SCARDHANDLE hCard, LPCBYTE lpbIn, DWORD dwIn, LPBYTE lpBOut, LPDWORD pdwOut);
// Buffers for APDU exchange
#define MAX_APDU 255
// Command header helpers
#define CLA(cla) UINT82XSCM(&phTmp->xSCM, cla, TYPE_NOTYPE_NOCOUNT)
#define INS(ins) UINT82XSCM(&phTmp->xSCM, ins, TYPE_NOTYPE_NOCOUNT)
#define P1(p1) UINT82XSCM(&phTmp->xSCM, p1, TYPE_NOTYPE_NOCOUNT)
#define P2(p2) UINT82XSCM(&phTmp->xSCM, p2, TYPE_NOTYPE_NOCOUNT)
#define Lc(lc) (phTmp->pbLc = GetSCMCrtPointer(&phTmp->xSCM), UINT82XSCM(&phTmp->xSCM, 0, TYPE_NOTYPE_NOCOUNT)) // We don't know at this time
#define UPDATE_Lc(lc) *phTmp->pbLc = lc
static SCODE ExtractSCODE(LPMYSCARDHANDLE phTmp, LPCBYTE abRAPDU, DWORD dwOut);
//*****************************************************************************
// EXPORTED API
//*****************************************************************************
/*
** AnA */ SCODE WINAPI hScwGetPrincipalUID(SCARDHANDLE hCard, WCSTR principalName, TUID *principalUID) { SCODE ret; DWORD dwOut, dwRet; BYTE abCAPDU[5+MAX_APDU]; BYTE abRAPDU[MAX_APDU]; LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
LOG_BEGIN_PROXY(hScwGetPrincipalUID);
// Marshaling
__try {
if (phTmp == NULL) RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
if ((phTmp->dwFlags & FLAG_ISPROXY) == 0) return SCW_E_NOTIMPLEMENTED;
InitXSCM(phTmp, abCAPDU, phTmp->bResLen); CLA(0x00); INS(phTmp->byINS); P1(2); P2(1); Lc(0); UINT82XSCM(&phTmp->xSCM, 2, TYPE_NOTYPE_COUNT); // Number of parameters
String2XSCM(&phTmp->xSCM, principalName, phTmp->dwFlags & FLAG_BIGENDIAN); UINT8BYREF2XSCM(&phTmp->xSCM, principalUID);
// API transfer
UPDATE_Lc((UINT8)(GetSCMBufferLength(&phTmp->xSCM)-5)); dwOut = MAX_APDU; dwRet = SCWTransmit(hCard, abCAPDU, (DWORD)GetSCMBufferLength(&phTmp->xSCM), abRAPDU, &dwOut);
if (dwRet == 0) { // Return code UnMarshaling
ret = ExtractSCODE(phTmp, abRAPDU, dwOut); } else ret = (SCODE)dwRet;
// Parameters UnMarshaling
if (ret == S_OK) { *principalUID = XSCM2UINT8(&phTmp->xSCM); } } __except(EXCEPTION_EXECUTE_HANDLER) {
switch(GetExceptionCode()) { case STATUS_INVALID_PARAM: ret = SCW_E_INVALIDPARAM; break;
case STATUS_INSUFFICIENT_MEM: ret = SCW_E_CANTMARSHAL; break;
case STATUS_INTERNAL_ERROR: ret = SCARD_F_INTERNAL_ERROR; break;
default: ret = SCARD_F_UNKNOWN_ERROR; } }
return ret; }
SCODE WINAPI hScwAuthenticateName(SCARDHANDLE hCard, WCSTR name , BYTE *supportData, TCOUNT supportDataLength) { SCODE ret; DWORD dwOut, dwRet; BYTE abCAPDU[5+MAX_APDU]; BYTE abRAPDU[MAX_APDU]; LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
LOG_BEGIN_PROXY(hScwAuthenticateName);
// Marshaling
__try {
if (phTmp == NULL) RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
if ((phTmp->dwFlags & FLAG_ISPROXY) == 0) return SCW_E_NOTIMPLEMENTED;
InitXSCM(phTmp, abCAPDU, phTmp->bResLen); CLA(0x00); INS(phTmp->byINS); P1(2); P2(2); Lc(0); UINT82XSCM(&phTmp->xSCM, 2, TYPE_NOTYPE_COUNT); // Number of parameters
String2XSCM(&phTmp->xSCM, name, phTmp->dwFlags & FLAG_BIGENDIAN); ByteArray2XSCM(&phTmp->xSCM, supportData, supportDataLength);
// API transfer
UPDATE_Lc((UINT8)(GetSCMBufferLength(&phTmp->xSCM)-5)); dwOut = 255; dwRet = SCWTransmit(hCard, abCAPDU, (DWORD)GetSCMBufferLength(&phTmp->xSCM), abRAPDU, &dwOut);
if (dwRet == 0) { // Return code UnMarshaling
ret = ExtractSCODE(phTmp, abRAPDU, dwOut); } else ret = (SCODE)dwRet;
// Parameters UnMarshaling
if (ret == S_OK) { }
} __except(EXCEPTION_EXECUTE_HANDLER) {
switch(GetExceptionCode()) { case STATUS_INVALID_PARAM: ret = SCW_E_INVALIDPARAM; break;
case STATUS_INSUFFICIENT_MEM: ret = SCW_E_CANTMARSHAL; break;
case STATUS_INTERNAL_ERROR: ret = SCARD_F_INTERNAL_ERROR; break;
default: ret = SCARD_F_UNKNOWN_ERROR; } }
return ret; }
SCODE WINAPI hScwAuthenticateUID(SCARDHANDLE hCard, TUID uid, BYTE *supportData, TCOUNT supportDataLength) { SCODE ret; DWORD dwOut, dwRet; BYTE abCAPDU[5+MAX_APDU]; BYTE abRAPDU[MAX_APDU]; LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
LOG_BEGIN_PROXY(hScwAuthenticateUID); // Marshaling
__try {
if (phTmp == NULL) RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
if ((phTmp->dwFlags & FLAG_ISPROXY) == 0) return SCW_E_NOTIMPLEMENTED;
InitXSCM(phTmp, abCAPDU, phTmp->bResLen); CLA(0x00); INS(phTmp->byINS); P1(2); P2(3); Lc(0); UINT82XSCM(&phTmp->xSCM, 2, TYPE_NOTYPE_COUNT); // Number of parameters
UINT82XSCM(&phTmp->xSCM, uid, TYPE_TYPED); ByteArray2XSCM(&phTmp->xSCM, supportData, supportDataLength);
// API transfer
UPDATE_Lc((UINT8)(GetSCMBufferLength(&phTmp->xSCM)-5)); dwOut = MAX_APDU; dwRet = SCWTransmit(hCard, abCAPDU, (DWORD)GetSCMBufferLength(&phTmp->xSCM), abRAPDU, &dwOut);
if (dwRet == 0) { // Return code UnMarshaling
ret = ExtractSCODE(phTmp, abRAPDU, dwOut); } else ret = (SCODE)dwRet;
// Parameters UnMarshaling
if (ret == S_OK) { }
} __except(EXCEPTION_EXECUTE_HANDLER) {
switch(GetExceptionCode()) { case STATUS_INVALID_PARAM: ret = SCW_E_INVALIDPARAM; break;
case STATUS_INSUFFICIENT_MEM: ret = SCW_E_CANTMARSHAL; break;
case STATUS_INTERNAL_ERROR: ret = SCARD_F_INTERNAL_ERROR; break;
default: ret = SCARD_F_UNKNOWN_ERROR; } }
return ret; }
SCODE WINAPI hScwDeauthenticateName(SCARDHANDLE hCard, WCSTR principalName) { SCODE ret; DWORD dwOut, dwRet; BYTE abCAPDU[5+MAX_APDU]; BYTE abRAPDU[MAX_APDU]; LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
LOG_BEGIN_PROXY(hScwDeauthenticateName);
// Marshaling
__try {
if (phTmp == NULL) RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
if ((phTmp->dwFlags & FLAG_ISPROXY) == 0) return SCW_E_NOTIMPLEMENTED;
InitXSCM(phTmp, abCAPDU, phTmp->bResLen); CLA(0x00); INS(phTmp->byINS); P1(2); P2(4); Lc(0); UINT82XSCM(&phTmp->xSCM, 1, TYPE_NOTYPE_COUNT); // Number of parameters
String2XSCM(&phTmp->xSCM, principalName, phTmp->dwFlags & FLAG_BIGENDIAN);
// API transfer
UPDATE_Lc((UINT8)(GetSCMBufferLength(&phTmp->xSCM)-5)); dwOut = MAX_APDU; dwRet = SCWTransmit(hCard, abCAPDU, (DWORD)GetSCMBufferLength(&phTmp->xSCM), abRAPDU, &dwOut);
if (dwRet == 0) { // Return code UnMarshaling
ret = ExtractSCODE(phTmp, abRAPDU, dwOut); } else ret = (SCODE)dwRet;
// Parameters UnMarshaling
if (ret == S_OK) { }
} __except(EXCEPTION_EXECUTE_HANDLER) {
switch(GetExceptionCode()) { case STATUS_INVALID_PARAM: ret = SCW_E_INVALIDPARAM; break;
case STATUS_INSUFFICIENT_MEM: ret = SCW_E_CANTMARSHAL; break;
case STATUS_INTERNAL_ERROR: ret = SCARD_F_INTERNAL_ERROR; break;
default: ret = SCARD_F_UNKNOWN_ERROR; } }
return ret; }
SCODE WINAPI hScwDeauthenticateUID(SCARDHANDLE hCard, TUID uid) { SCODE ret; DWORD dwOut, dwRet; BYTE abCAPDU[5+MAX_APDU]; BYTE abRAPDU[MAX_APDU]; LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
LOG_BEGIN_PROXY(hScwDeauthenticateUID);
// Marshaling
__try {
if (phTmp == NULL) RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
if ((phTmp->dwFlags & FLAG_ISPROXY) == 0) return SCW_E_NOTIMPLEMENTED;
InitXSCM(phTmp, abCAPDU, phTmp->bResLen); CLA(0x00); INS(phTmp->byINS); P1(2); P2(5); Lc(0); UINT82XSCM(&phTmp->xSCM, 1, TYPE_NOTYPE_COUNT); // Number of parameters
UINT82XSCM(&phTmp->xSCM, uid, TYPE_TYPED);
// API transfer
UPDATE_Lc((UINT8)(GetSCMBufferLength(&phTmp->xSCM)-5)); dwOut = MAX_APDU; dwRet = SCWTransmit(hCard, abCAPDU, (DWORD)GetSCMBufferLength(&phTmp->xSCM), abRAPDU, &dwOut);
if (dwRet == 0) { // Return code UnMarshaling
ret = ExtractSCODE(phTmp, abRAPDU, dwOut); } else ret = (SCODE)dwRet;
// Parameters UnMarshaling
if (ret == S_OK) { }
} __except(EXCEPTION_EXECUTE_HANDLER) {
switch(GetExceptionCode()) { case STATUS_INVALID_PARAM: ret = SCW_E_INVALIDPARAM; break;
case STATUS_INSUFFICIENT_MEM: ret = SCW_E_CANTMARSHAL; break;
case STATUS_INTERNAL_ERROR: ret = SCARD_F_INTERNAL_ERROR; break;
default: ret = SCARD_F_UNKNOWN_ERROR; } }
return ret; }
SCODE WINAPI hScwIsAuthenticatedName(SCARDHANDLE hCard, WCSTR principalName) { SCODE ret; DWORD dwOut, dwRet; BYTE abCAPDU[5+MAX_APDU]; BYTE abRAPDU[MAX_APDU]; LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
LOG_BEGIN_PROXY(hScwIsAuthenticatedName);
// Marshaling
__try {
if (phTmp == NULL) RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
if ((phTmp->dwFlags & FLAG_ISPROXY) == 0) return SCW_E_NOTIMPLEMENTED;
InitXSCM(phTmp, abCAPDU, phTmp->bResLen); CLA(0x00); INS(phTmp->byINS); P1(2); P2(6); Lc(0); UINT82XSCM(&phTmp->xSCM, 1, TYPE_NOTYPE_COUNT); // Number of parameters
String2XSCM(&phTmp->xSCM, principalName, phTmp->dwFlags & FLAG_BIGENDIAN);
// API transfer
UPDATE_Lc((UINT8)(GetSCMBufferLength(&phTmp->xSCM)-5)); dwOut = MAX_APDU; dwRet = SCWTransmit(hCard, abCAPDU, (DWORD)GetSCMBufferLength(&phTmp->xSCM), abRAPDU, &dwOut);
if (dwRet == 0) { // Return code UnMarshaling
ret = ExtractSCODE(phTmp, abRAPDU, dwOut); } else ret = (SCODE)dwRet;
// Parameters UnMarshaling
if (ret == S_OK) { }
} __except(EXCEPTION_EXECUTE_HANDLER) {
switch(GetExceptionCode()) { case STATUS_INVALID_PARAM: ret = SCW_E_INVALIDPARAM; break;
case STATUS_INSUFFICIENT_MEM: ret = SCW_E_CANTMARSHAL; break;
case STATUS_INTERNAL_ERROR: ret = SCARD_F_INTERNAL_ERROR; break;
default: ret = SCARD_F_UNKNOWN_ERROR; } }
return ret; }
SCODE WINAPI hScwIsAuthenticatedUID(SCARDHANDLE hCard, TUID uid) { SCODE ret; DWORD dwOut, dwRet; BYTE abCAPDU[5+MAX_APDU]; BYTE abRAPDU[MAX_APDU]; LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
LOG_BEGIN_PROXY(hScwIsAuthenticatedUID);
// Marshaling
__try {
if (phTmp == NULL) RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
if ((phTmp->dwFlags & FLAG_ISPROXY) == 0) return SCW_E_NOTIMPLEMENTED;
InitXSCM(phTmp, abCAPDU, phTmp->bResLen); CLA(0x00); INS(phTmp->byINS); P1(2); P2(7); Lc(0); UINT82XSCM(&phTmp->xSCM, 1, TYPE_NOTYPE_COUNT); // Number of parameters
UINT82XSCM(&phTmp->xSCM, uid, TYPE_TYPED);
// API transfer
UPDATE_Lc((UINT8)(GetSCMBufferLength(&phTmp->xSCM)-5)); dwOut = MAX_APDU; dwRet = SCWTransmit(hCard, abCAPDU, (DWORD)GetSCMBufferLength(&phTmp->xSCM), abRAPDU, &dwOut);
if (dwRet == 0) { // Return code UnMarshaling
ret = ExtractSCODE(phTmp, abRAPDU, dwOut); } else ret = (SCODE)dwRet;
// Parameters UnMarshaling
if (ret == S_OK) { }
} __except(EXCEPTION_EXECUTE_HANDLER) {
switch(GetExceptionCode()) { case STATUS_INVALID_PARAM: ret = SCW_E_INVALIDPARAM; break;
case STATUS_INSUFFICIENT_MEM: ret = SCW_E_CANTMARSHAL; break;
case STATUS_INTERNAL_ERROR: ret = SCARD_F_INTERNAL_ERROR; break;
default: ret = SCARD_F_UNKNOWN_ERROR; } }
return ret; }
SCODE WINAPI hScwIsAuthorized(SCARDHANDLE hCard, WCSTR resourceName, BYTE operation) { SCODE ret; DWORD dwOut, dwRet; BYTE abCAPDU[5+MAX_APDU]; BYTE abRAPDU[MAX_APDU]; LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
LOG_BEGIN_PROXY(hScwIsAuthorized);
// Marshaling
__try {
if (phTmp == NULL) RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
if ((phTmp->dwFlags & FLAG_ISPROXY) == 0) return SCW_E_NOTIMPLEMENTED;
InitXSCM(phTmp, abCAPDU, phTmp->bResLen); CLA(0x00); INS(phTmp->byINS); P1(2); P2(8); Lc(0); // UINT82XSCM(&phTmp->xSCM, 3, TYPE_NOTYPE_COUNT); // Number of parameters
UINT82XSCM(&phTmp->xSCM, 2, TYPE_NOTYPE_COUNT); // Number of parameters
// UINT82XSCM(&phTmp->xSCM, resourceType, TYPE_TYPED);
String2XSCM(&phTmp->xSCM, resourceName, phTmp->dwFlags & FLAG_BIGENDIAN); UINT82XSCM(&phTmp->xSCM, operation, TYPE_TYPED);
// API transfer
UPDATE_Lc((UINT8)(GetSCMBufferLength(&phTmp->xSCM)-5)); dwOut = MAX_APDU; dwRet = SCWTransmit(hCard, abCAPDU, (DWORD)GetSCMBufferLength(&phTmp->xSCM), abRAPDU, &dwOut);
if (dwRet == 0) { // Return code UnMarshaling
ret = ExtractSCODE(phTmp, abRAPDU, dwOut); } else ret = (SCODE)dwRet;
// Parameters UnMarshaling
if (ret == S_OK) { }
} __except(EXCEPTION_EXECUTE_HANDLER) {
switch(GetExceptionCode()) { case STATUS_INVALID_PARAM: ret = SCW_E_INVALIDPARAM; break;
case STATUS_INSUFFICIENT_MEM: ret = SCW_E_CANTMARSHAL; break;
case STATUS_INTERNAL_ERROR: ret = SCARD_F_INTERNAL_ERROR; break;
default: ret = SCARD_F_UNKNOWN_ERROR; } }
return ret; }
/*
** File System */
SCODE WINAPI hScwCreateFile(SCARDHANDLE hCard, WCSTR fileName, WCSTR aclFileName, HFILE *phFile) { SCODE ret; DWORD dwOut, dwRet; BYTE abCAPDU[5+MAX_APDU]; BYTE abRAPDU[MAX_APDU]; LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
LOG_BEGIN_PROXY(hScwCreateFile); // Marshaling
__try {
if (phTmp == NULL) RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
if ((phTmp->dwFlags & FLAG_ISPROXY) == 0) return SCW_E_NOTIMPLEMENTED;
InitXSCM(phTmp, abCAPDU, phTmp->bResLen); CLA(0x00); INS(phTmp->byINS); P1(3); P2(1); Lc(0); UINT82XSCM(&phTmp->xSCM, 3, TYPE_NOTYPE_COUNT); // Number of parameters
String2XSCM(&phTmp->xSCM, fileName, phTmp->dwFlags & FLAG_BIGENDIAN); String2XSCM(&phTmp->xSCM, aclFileName, phTmp->dwFlags & FLAG_BIGENDIAN); HFILEBYREF2XSCM(&phTmp->xSCM, phFile);
// API transfer
UPDATE_Lc((UINT8)(GetSCMBufferLength(&phTmp->xSCM)-5)); dwOut = MAX_APDU; dwRet = SCWTransmit(hCard, abCAPDU, (DWORD)GetSCMBufferLength(&phTmp->xSCM), abRAPDU, &dwOut);
if (dwRet == 0) { // Return code UnMarshaling
ret = ExtractSCODE(phTmp, abRAPDU, dwOut); } else ret = (SCODE)dwRet;
// Parameters UnMarshaling
if (ret == S_OK) { if (phFile) *phFile = XSCM2HFILE(&phTmp->xSCM); }
} __except(EXCEPTION_EXECUTE_HANDLER) {
switch(GetExceptionCode()) { case STATUS_INVALID_PARAM: ret = SCW_E_INVALIDPARAM; break;
case STATUS_INSUFFICIENT_MEM: ret = SCW_E_CANTMARSHAL; break;
case STATUS_INTERNAL_ERROR: ret = SCARD_F_INTERNAL_ERROR; break;
default: ret = SCARD_F_UNKNOWN_ERROR; } }
return ret; }
SCODE WINAPI hScwDeleteFile(SCARDHANDLE hCard, WCSTR fileName) { SCODE ret; DWORD dwOut, dwRet; BYTE abCAPDU[5+MAX_APDU]; BYTE abRAPDU[MAX_APDU]; LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
LOG_BEGIN_PROXY(hScwDeleteFile);
// Marshaling
__try {
if (phTmp == NULL) RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
if ((phTmp->dwFlags & FLAG_ISPROXY) == 0) return SCW_E_NOTIMPLEMENTED;
InitXSCM(phTmp, abCAPDU, phTmp->bResLen); CLA(0x00); INS(phTmp->byINS); P1(3); P2(2); Lc(0); UINT82XSCM(&phTmp->xSCM, 1, TYPE_NOTYPE_COUNT); // Number of parameters
String2XSCM(&phTmp->xSCM, fileName, phTmp->dwFlags & FLAG_BIGENDIAN);
// API transfer
UPDATE_Lc((UINT8)(GetSCMBufferLength(&phTmp->xSCM)-5)); dwOut = MAX_APDU; dwRet = SCWTransmit(hCard, abCAPDU, (DWORD)GetSCMBufferLength(&phTmp->xSCM), abRAPDU, &dwOut);
if (dwRet == 0) { // Return code UnMarshaling
ret = ExtractSCODE(phTmp, abRAPDU, dwOut); } else ret = (SCODE)dwRet;
// Parameters UnMarshaling
if (ret == S_OK) { }
} __except(EXCEPTION_EXECUTE_HANDLER) {
switch(GetExceptionCode()) { case STATUS_INVALID_PARAM: ret = SCW_E_INVALIDPARAM; break;
case STATUS_INSUFFICIENT_MEM: ret = SCW_E_CANTMARSHAL; break;
case STATUS_INTERNAL_ERROR: ret = SCARD_F_INTERNAL_ERROR; break;
default: ret = SCARD_F_UNKNOWN_ERROR; } }
return ret; }
SCODE WINAPI hScwCloseFile(SCARDHANDLE hCard, HFILE hFile) { SCODE ret; DWORD dwOut, dwRet; BYTE abCAPDU[5+MAX_APDU]; BYTE abRAPDU[MAX_APDU]; LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
LOG_BEGIN_PROXY(hScwCloseFile);
// Marshaling
__try {
if (phTmp == NULL) RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
if ((phTmp->dwFlags & FLAG_ISPROXY) == 0) return SCW_E_NOTIMPLEMENTED;
InitXSCM(phTmp, abCAPDU, phTmp->bResLen); CLA(0x00); INS(phTmp->byINS); P1(3); P2(4); Lc(0); UINT82XSCM(&phTmp->xSCM, 1, TYPE_NOTYPE_COUNT); // Number of parameters
HFILE2XSCM(&phTmp->xSCM, hFile);
// API transfer
UPDATE_Lc((UINT8)(GetSCMBufferLength(&phTmp->xSCM)-5)); dwOut = MAX_APDU; dwRet = SCWTransmit(hCard, abCAPDU, (DWORD)GetSCMBufferLength(&phTmp->xSCM), abRAPDU, &dwOut);
if (dwRet == 0) { // Return code UnMarshaling
ret = ExtractSCODE(phTmp, abRAPDU, dwOut); } else ret = (SCODE)dwRet;
// Parameters UnMarshaling
if (ret == S_OK) { }
} __except(EXCEPTION_EXECUTE_HANDLER) {
switch(GetExceptionCode()) { case STATUS_INVALID_PARAM: ret = SCW_E_INVALIDPARAM; break;
case STATUS_INSUFFICIENT_MEM: ret = SCW_E_CANTMARSHAL; break;
case STATUS_INTERNAL_ERROR: ret = SCARD_F_INTERNAL_ERROR; break;
default: ret = SCARD_F_UNKNOWN_ERROR; } }
return ret; }
SCODE __hScwReadFile(SCARDHANDLE hCard, HFILE hFile, BYTE *buffer, TCOUNT length, TCOUNT *bytesRead) { SCODE ret; DWORD dwOut, dwRet; BYTE abCAPDU[5+MAX_APDU]; BYTE abRAPDU[MAX_APDU]; LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
LOG_BEGIN_PROXY(hScwReadFile);
// Marshaling
__try {
if (phTmp == NULL) RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
if ((phTmp->dwFlags & FLAG_ISPROXY) == 0) return SCW_E_NOTIMPLEMENTED;
InitXSCM(phTmp, abCAPDU, phTmp->bResLen); CLA(0x00); INS(phTmp->byINS); P1(3); P2(5); Lc(0); UINT82XSCM(&phTmp->xSCM, 3, TYPE_NOTYPE_COUNT); // Number of parameters
HFILE2XSCM(&phTmp->xSCM, hFile); ByteArrayOut2XSCM(&phTmp->xSCM, buffer, length); UINT8BYREF2XSCM(&phTmp->xSCM, bytesRead);
// API transfer
UPDATE_Lc((UINT8)(GetSCMBufferLength(&phTmp->xSCM)-5)); dwOut = MAX_APDU; dwRet = SCWTransmit(hCard, abCAPDU, (DWORD)GetSCMBufferLength(&phTmp->xSCM), abRAPDU, &dwOut);
if (dwRet == 0) { // Return code UnMarshaling
ret = ExtractSCODE(phTmp, abRAPDU, dwOut); } else ret = (SCODE)dwRet;
// Parameters UnMarshaling
if (ret == S_OK) { BYTE *_pbBuffer; UINT8 len;
len = XSCM2ByteArray(&phTmp->xSCM, &_pbBuffer); *bytesRead = XSCM2UINT8(&phTmp->xSCM); memcpy(buffer, _pbBuffer, *bytesRead); }
} __except(EXCEPTION_EXECUTE_HANDLER) {
switch(GetExceptionCode()) { case STATUS_INVALID_PARAM: ret = SCW_E_INVALIDPARAM; break;
case STATUS_INSUFFICIENT_MEM: ret = SCW_E_CANTMARSHAL; break;
case STATUS_INTERNAL_ERROR: ret = SCARD_F_INTERNAL_ERROR; break;
default: ret = SCARD_F_UNKNOWN_ERROR; } }
return ret; }
SCODE WINAPI hScwReadFile32(SCARDHANDLE hCard, HFILE hFile, BYTE *pbBuffer, DWORD nRequestedBytes, DWORD *pnActualBytes) { SCODE ret; TCOUNT nNow, nOpt, nRead; DWORD nOverall = 0; LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
// Marshaling
__try {
if ((phTmp == NULL) || (pnActualBytes == NULL)) RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
// v1.0 IN: #param | 8 | HFILE | a | L | 108 | Read / OUT: RC | L | Data | Read | SW (already deducted so max = bResLen-10)
// v1.1 IN: #param | 8 | HFILE | a | L | 108 | Read / OUT: L | Data | Read | SW (already deducted so max = bResLen-9)
if (FLAG2VERSION(phTmp->dwFlags) == VERSION_1_0) { if (phTmp->bResLen < 10) RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0); } else if (FLAG2VERSION(phTmp->dwFlags) == VERSION_1_1) { if (phTmp->bResLen < 9) RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0); } else RaiseException(STATUS_INTERNAL_ERROR, 0, 0, 0);
nOpt = phTmp->bResLen - 9; // Biggest possible
if (FLAG2VERSION(phTmp->dwFlags) == VERSION_1_0) nOpt--;
do { nNow = (TCOUNT)((nRequestedBytes - nOverall > nOpt) ? nOpt : nRequestedBytes - nOverall);
ret = __hScwReadFile(hCard, hFile, pbBuffer+nOverall, nNow, &nRead);
if (FAILED(ret)) break;
nOverall += nRead; } while ((nOverall < nRequestedBytes) && (nRead == nNow));
if (!(FAILED(ret))) *pnActualBytes = nOverall; } __except(EXCEPTION_EXECUTE_HANDLER) {
switch(GetExceptionCode()) { case STATUS_INVALID_PARAM: ret = SCW_E_INVALIDPARAM; break;
case STATUS_INSUFFICIENT_MEM: ret = SCW_E_CANTMARSHAL; break;
case STATUS_INTERNAL_ERROR: ret = SCARD_F_INTERNAL_ERROR; break;
default: ret = SCARD_F_UNKNOWN_ERROR; } }
return ret; }
SCODE WINAPI hScwReadFile(SCARDHANDLE hCard, HFILE hFile, BYTE *pbBuffer, TCOUNT nRequestedBytes, TCOUNT *pnActualBytes) { DWORD cbActual; SCODE ret;
if (IsBadWritePtr(pnActualBytes, 1)) ret = hScwReadFile32(hCard, hFile, pbBuffer, (DWORD)nRequestedBytes, NULL); else { ret = hScwReadFile32(hCard, hFile, pbBuffer, (DWORD)nRequestedBytes, &cbActual); if (!FAILED(ret)) *pnActualBytes = (TCOUNT)cbActual; } return ret; }
SCODE __hScwWriteFile(SCARDHANDLE hCard, HFILE hFile, BYTE *buffer, TCOUNT length, TCOUNT *bytesWritten) { SCODE ret; DWORD dwOut, dwRet; BYTE abCAPDU[5+MAX_APDU]; BYTE abRAPDU[MAX_APDU]; LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
LOG_BEGIN_PROXY(hScwWriteFile);
// Marshaling
__try {
if (phTmp == NULL) RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
if ((phTmp->dwFlags & FLAG_ISPROXY) == 0) return SCW_E_NOTIMPLEMENTED;
InitXSCM(phTmp, abCAPDU, phTmp->bResLen); CLA(0x00); INS(phTmp->byINS); P1(3); P2(6); Lc(0); UINT82XSCM(&phTmp->xSCM, 3, TYPE_NOTYPE_COUNT); // Number of parameters
HFILE2XSCM(&phTmp->xSCM, hFile); ByteArray2XSCM(&phTmp->xSCM, buffer, length); UINT8BYREF2XSCM(&phTmp->xSCM, bytesWritten);
// API transfer
UPDATE_Lc((UINT8)(GetSCMBufferLength(&phTmp->xSCM)-5)); dwOut = MAX_APDU; dwRet = SCWTransmit(hCard, abCAPDU, (DWORD)GetSCMBufferLength(&phTmp->xSCM), abRAPDU, &dwOut);
if (dwRet == 0) { // Return code UnMarshaling
ret = ExtractSCODE(phTmp, abRAPDU, dwOut); } else ret = (SCODE)dwRet;
// Parameters UnMarshaling
if (ret == S_OK) { *bytesWritten = XSCM2UINT8(&phTmp->xSCM); }
} __except(EXCEPTION_EXECUTE_HANDLER) {
switch(GetExceptionCode()) { case STATUS_INVALID_PARAM: ret = SCW_E_INVALIDPARAM; break;
case STATUS_INSUFFICIENT_MEM: ret = SCW_E_CANTMARSHAL; break;
case STATUS_INTERNAL_ERROR: ret = SCARD_F_INTERNAL_ERROR; break;
default: ret = SCARD_F_UNKNOWN_ERROR; } }
return ret; }
SCODE WINAPI hScwWriteFile32(SCARDHANDLE hCard, HFILE hFile, BYTE *pbBuffer, DWORD nRequestedBytes, DWORD *pnActualBytes) { SCODE ret; TCOUNT nNow, nOpt, nWritten; DWORD nOverall = 0; LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
// Marshaling
__try {
if ((phTmp == NULL) || (pnActualBytes == NULL)) RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
// v1.0 IN: #param | 8 | HFILE | A | L | Data | 108 | Written / OUT: RC | Written | SW (already deducted so max = bResLen-9)
// v1.1 IN: #param | 8 | HFILE | A | L | Data | 108 | Written / OUT: Written | SW (already deducted so max = bResLen-8)
if (FLAG2VERSION(phTmp->dwFlags) == VERSION_1_0) { if (phTmp->bResLen < 9) RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0); } else if (FLAG2VERSION(phTmp->dwFlags) == VERSION_1_1) { if (phTmp->bResLen < 8) RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0); } else RaiseException(STATUS_INTERNAL_ERROR, 0, 0, 0);
nOpt = phTmp->bResLen - 8; // Biggest possible
if (FLAG2VERSION(phTmp->dwFlags) == VERSION_1_0) nOpt--;
do { nNow = (TCOUNT)((nRequestedBytes - nOverall > (TCOUNT)nOpt) ? nOpt : nRequestedBytes - nOverall);
ret = __hScwWriteFile(hCard, hFile, pbBuffer+nOverall, nNow, &nWritten);
if (FAILED(ret)) break;
nOverall += nWritten; } while ((nOverall < nRequestedBytes) && (nWritten == nNow));
if (!(FAILED(ret))) *pnActualBytes = nOverall; } __except(EXCEPTION_EXECUTE_HANDLER) {
switch(GetExceptionCode()) { case STATUS_INVALID_PARAM: ret = SCW_E_INVALIDPARAM; break;
case STATUS_INSUFFICIENT_MEM: ret = SCW_E_CANTMARSHAL; break;
case STATUS_INTERNAL_ERROR: ret = SCARD_F_INTERNAL_ERROR; break;
default: ret = SCARD_F_UNKNOWN_ERROR; } }
return ret; }
SCODE WINAPI hScwWriteFile(SCARDHANDLE hCard, HFILE hFile, BYTE *pbBuffer, TCOUNT nRequestedBytes, TCOUNT *pnActualBytes) { DWORD cbActual; SCODE ret;
if (IsBadWritePtr(pnActualBytes, 1)) ret = hScwWriteFile32(hCard, hFile, pbBuffer, (DWORD)nRequestedBytes, NULL); else { ret = hScwWriteFile32(hCard, hFile, pbBuffer, (DWORD)nRequestedBytes, &cbActual); if (!FAILED(ret)) *pnActualBytes = (TCOUNT)cbActual; } return ret; }
SCODE WINAPI hScwGetFileLength(SCARDHANDLE hCard, HFILE hFile, TOFFSET *fileSize) { SCODE ret; DWORD dwOut, dwRet; BYTE abCAPDU[5+MAX_APDU]; BYTE abRAPDU[MAX_APDU]; LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
LOG_BEGIN_PROXY(hScwGetFileLength);
// Marshaling
__try {
if (phTmp == NULL) RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
if ((phTmp->dwFlags & FLAG_ISPROXY) == 0) return SCW_E_NOTIMPLEMENTED;
InitXSCM(phTmp, abCAPDU, phTmp->bResLen); CLA(0x00); INS(phTmp->byINS); P1(3); P2(7); Lc(0); UINT82XSCM(&phTmp->xSCM, 2, TYPE_NOTYPE_COUNT); // Number of parameters
HFILE2XSCM(&phTmp->xSCM, hFile); UINT16BYREF2XSCM(&phTmp->xSCM, fileSize, phTmp->dwFlags & FLAG_BIGENDIAN);
// API transfer
UPDATE_Lc((UINT8)(GetSCMBufferLength(&phTmp->xSCM)-5)); dwOut = MAX_APDU; dwRet = SCWTransmit(hCard, abCAPDU, (DWORD)GetSCMBufferLength(&phTmp->xSCM), abRAPDU, &dwOut);
if (dwRet == 0) { // Return code UnMarshaling
ret = ExtractSCODE(phTmp, abRAPDU, dwOut); } else ret = (SCODE)dwRet;
// Parameters UnMarshaling
if (ret == S_OK) { *fileSize = XSCM2UINT16(&phTmp->xSCM, phTmp->dwFlags & FLAG_BIGENDIAN); }
} __except(EXCEPTION_EXECUTE_HANDLER) {
switch(GetExceptionCode()) { case STATUS_INVALID_PARAM: ret = SCW_E_INVALIDPARAM; break;
case STATUS_INSUFFICIENT_MEM: ret = SCW_E_CANTMARSHAL; break;
case STATUS_INTERNAL_ERROR: ret = SCARD_F_INTERNAL_ERROR; break;
default: ret = SCARD_F_UNKNOWN_ERROR; } }
return ret; }
SCODE WINAPI hScwSetFileLength(SCARDHANDLE hCard, HFILE hFile, TOFFSET fileSize) { SCODE ret; DWORD dwOut, dwRet; BYTE abCAPDU[5+MAX_APDU]; BYTE abRAPDU[MAX_APDU]; LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
LOG_BEGIN_PROXY(hScwSetFileLength); // Marshaling
__try {
if (phTmp == NULL) RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
if ((phTmp->dwFlags & FLAG_ISPROXY) == 0) return SCW_E_NOTIMPLEMENTED;
InitXSCM(phTmp, abCAPDU, phTmp->bResLen); CLA(0x00); INS(phTmp->byINS); P1(3); P2(8); Lc(0); UINT82XSCM(&phTmp->xSCM, 2, TYPE_NOTYPE_COUNT); // Number of parameters
HFILE2XSCM(&phTmp->xSCM, hFile); UINT162XSCM(&phTmp->xSCM, fileSize, phTmp->dwFlags & FLAG_BIGENDIAN);
// API transfer
UPDATE_Lc((UINT8)(GetSCMBufferLength(&phTmp->xSCM)-5)); dwOut = MAX_APDU; dwRet = SCWTransmit(hCard, abCAPDU, (DWORD)GetSCMBufferLength(&phTmp->xSCM), abRAPDU, &dwOut);
if (dwRet == 0) { // Return code UnMarshaling
ret = ExtractSCODE(phTmp, abRAPDU, dwOut); } else ret = (SCODE)dwRet;
// Parameters UnMarshaling
if (ret == S_OK) { }
} __except(EXCEPTION_EXECUTE_HANDLER) {
switch(GetExceptionCode()) { case STATUS_INVALID_PARAM: ret = SCW_E_INVALIDPARAM; break;
case STATUS_INSUFFICIENT_MEM: ret = SCW_E_CANTMARSHAL; break;
case STATUS_INTERNAL_ERROR: ret = SCARD_F_INTERNAL_ERROR; break;
default: ret = SCARD_F_UNKNOWN_ERROR; } }
return ret; }
SCODE WINAPI hScwSetFilePointer(SCARDHANDLE hCard, HFILE hFile, INT16 offset, BYTE mode) { SCODE ret; DWORD dwOut, dwRet; BYTE abCAPDU[5+MAX_APDU]; BYTE abRAPDU[MAX_APDU]; LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
LOG_BEGIN_PROXY(hScwSetFilePointer);
// Marshaling
__try {
if (phTmp == NULL) RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
if ((phTmp->dwFlags & FLAG_ISPROXY) == 0) return SCW_E_NOTIMPLEMENTED;
InitXSCM(phTmp, abCAPDU, phTmp->bResLen); CLA(0x00); INS(phTmp->byINS); P1(3); P2(9); Lc(0); UINT82XSCM(&phTmp->xSCM, 3, TYPE_NOTYPE_COUNT); // Number of parameters
HFILE2XSCM(&phTmp->xSCM, hFile); UINT162XSCM(&phTmp->xSCM, (UINT16)offset, phTmp->dwFlags & FLAG_BIGENDIAN); UINT82XSCM(&phTmp->xSCM, mode, TYPE_TYPED);
// API transfer
UPDATE_Lc((UINT8)(GetSCMBufferLength(&phTmp->xSCM)-5)); dwOut = MAX_APDU; dwRet = SCWTransmit(hCard, abCAPDU, (DWORD)GetSCMBufferLength(&phTmp->xSCM), abRAPDU, &dwOut);
if (dwRet == 0) { // Return code UnMarshaling
ret = ExtractSCODE(phTmp, abRAPDU, dwOut); } else ret = (SCODE)dwRet;
// Parameters UnMarshaling
if (ret == S_OK) { }
} __except(EXCEPTION_EXECUTE_HANDLER) {
switch(GetExceptionCode()) { case STATUS_INVALID_PARAM: ret = SCW_E_INVALIDPARAM; break;
case STATUS_INSUFFICIENT_MEM: ret = SCW_E_CANTMARSHAL; break;
case STATUS_INTERNAL_ERROR: ret = SCARD_F_INTERNAL_ERROR; break;
default: ret = SCARD_F_UNKNOWN_ERROR; } }
return ret; }
SCODE WINAPI hScwGetFileAttributes(SCARDHANDLE hCard, WCSTR fileName, UINT16 *attributeValue) { SCODE ret; DWORD dwOut, dwRet; BYTE abCAPDU[5+MAX_APDU]; BYTE abRAPDU[MAX_APDU]; LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
LOG_BEGIN_PROXY(hScwGetFileAttributes);
// Marshaling
__try {
if (phTmp == NULL) RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
if ((phTmp->dwFlags & FLAG_ISPROXY) == 0) return SCW_E_NOTIMPLEMENTED;
InitXSCM(phTmp, abCAPDU, phTmp->bResLen); CLA(0x00); INS(phTmp->byINS); P1(3); P2(11); Lc(0); UINT82XSCM(&phTmp->xSCM, 2, TYPE_NOTYPE_COUNT); // Number of parameters
String2XSCM(&phTmp->xSCM, fileName, phTmp->dwFlags & FLAG_BIGENDIAN); UINT16BYREF2XSCM(&phTmp->xSCM, attributeValue, phTmp->dwFlags & FLAG_BIGENDIAN);
// API transfer
UPDATE_Lc((UINT8)(GetSCMBufferLength(&phTmp->xSCM)-5)); dwOut = MAX_APDU; dwRet = SCWTransmit(hCard, abCAPDU, (DWORD)GetSCMBufferLength(&phTmp->xSCM), abRAPDU, &dwOut);
if (dwRet == 0) { // Return code UnMarshaling
ret = ExtractSCODE(phTmp, abRAPDU, dwOut); } else ret = (SCODE)dwRet;
// Parameters UnMarshaling
if (ret == S_OK) { *attributeValue = XSCM2UINT16(&phTmp->xSCM, phTmp->dwFlags & FLAG_BIGENDIAN); }
} __except(EXCEPTION_EXECUTE_HANDLER) {
switch(GetExceptionCode()) { case STATUS_INVALID_PARAM: ret = SCW_E_INVALIDPARAM; break;
case STATUS_INSUFFICIENT_MEM: ret = SCW_E_CANTMARSHAL; break;
case STATUS_INTERNAL_ERROR: ret = SCARD_F_INTERNAL_ERROR; break;
default: ret = SCARD_F_UNKNOWN_ERROR; } }
return ret; }
SCODE WINAPI hScwSetFileAttributes(SCARDHANDLE hCard, WCSTR fileName, UINT16 attributeValue) { SCODE ret; DWORD dwOut, dwRet; BYTE abCAPDU[5+MAX_APDU]; BYTE abRAPDU[MAX_APDU]; LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
LOG_BEGIN_PROXY(hScwSetFileAttributes);
// Marshaling
__try {
if (phTmp == NULL) RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
if ((phTmp->dwFlags & FLAG_ISPROXY) == 0) return SCW_E_NOTIMPLEMENTED;
InitXSCM(phTmp, abCAPDU, phTmp->bResLen); CLA(0x00); INS(phTmp->byINS); P1(3); P2(12); Lc(0); UINT82XSCM(&phTmp->xSCM, 2, TYPE_NOTYPE_COUNT); // Number of parameters
String2XSCM(&phTmp->xSCM, fileName, phTmp->dwFlags & FLAG_BIGENDIAN); UINT162XSCM(&phTmp->xSCM, attributeValue, phTmp->dwFlags & FLAG_BIGENDIAN);
// API transfer
UPDATE_Lc((UINT8)(GetSCMBufferLength(&phTmp->xSCM)-5)); dwOut = MAX_APDU; dwRet = SCWTransmit(hCard, abCAPDU, (DWORD)GetSCMBufferLength(&phTmp->xSCM), abRAPDU, &dwOut);
if (dwRet == 0) { // Return code UnMarshaling
ret = ExtractSCODE(phTmp, abRAPDU, dwOut); } else ret = (SCODE)dwRet;
// Parameters UnMarshaling
if (ret == S_OK) { }
} __except(EXCEPTION_EXECUTE_HANDLER) {
switch(GetExceptionCode()) { case STATUS_INVALID_PARAM: ret = SCW_E_INVALIDPARAM; break;
case STATUS_INSUFFICIENT_MEM: ret = SCW_E_CANTMARSHAL; break;
case STATUS_INTERNAL_ERROR: ret = SCARD_F_INTERNAL_ERROR; break;
default: ret = SCARD_F_UNKNOWN_ERROR; } }
return ret; }
SCODE WINAPI hScwSetFileACL(SCARDHANDLE hCard, WCSTR fileName, WCSTR aclFileName) { SCODE ret; DWORD dwOut, dwRet; BYTE abCAPDU[5+MAX_APDU]; BYTE abRAPDU[MAX_APDU]; LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
LOG_BEGIN_PROXY(hScwSetFileACL);
// Marshaling
__try {
if (phTmp == NULL) RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
if ((phTmp->dwFlags & FLAG_ISPROXY) == 0) return SCW_E_NOTIMPLEMENTED;
InitXSCM(phTmp, abCAPDU, phTmp->bResLen); CLA(0x00); INS(phTmp->byINS); P1(3); P2(13); Lc(0); UINT82XSCM(&phTmp->xSCM, 2, TYPE_NOTYPE_COUNT); // Number of parameters
String2XSCM(&phTmp->xSCM, fileName, phTmp->dwFlags & FLAG_BIGENDIAN); String2XSCM(&phTmp->xSCM, aclFileName, phTmp->dwFlags & FLAG_BIGENDIAN);
// API transfer
UPDATE_Lc((UINT8)(GetSCMBufferLength(&phTmp->xSCM)-5)); dwOut = MAX_APDU; dwRet = SCWTransmit(hCard, abCAPDU, (DWORD)GetSCMBufferLength(&phTmp->xSCM), abRAPDU, &dwOut);
if (dwRet == 0) { // Return code UnMarshaling
ret = ExtractSCODE(phTmp, abRAPDU, dwOut); } else ret = (SCODE)dwRet;
// Parameters UnMarshaling
if (ret == S_OK) { }
} __except(EXCEPTION_EXECUTE_HANDLER) {
switch(GetExceptionCode()) { case STATUS_INVALID_PARAM: ret = SCW_E_INVALIDPARAM; break;
case STATUS_INSUFFICIENT_MEM: ret = SCW_E_CANTMARSHAL; break;
case STATUS_INTERNAL_ERROR: ret = SCARD_F_INTERNAL_ERROR; break;
default: ret = SCARD_F_UNKNOWN_ERROR; } }
return ret; }
SCODE WINAPI hScwGetFileAclHandle(SCARDHANDLE hCard, WCSTR fileName, HFILE *phFile) { SCODE ret; DWORD dwOut, dwRet; BYTE abCAPDU[5+MAX_APDU]; BYTE abRAPDU[MAX_APDU]; LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
LOG_BEGIN_PROXY(hScwGetFileAclHandle);
// Marshaling
__try {
if (phTmp == NULL) RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
if ((phTmp->dwFlags & FLAG_ISPROXY) == 0) return SCW_E_NOTIMPLEMENTED;
InitXSCM(phTmp, abCAPDU, phTmp->bResLen); CLA(0x00); INS(phTmp->byINS); P1(3); P2(14); Lc(0); UINT82XSCM(&phTmp->xSCM, 2, TYPE_NOTYPE_COUNT); // Number of parameters
String2XSCM(&phTmp->xSCM, fileName, phTmp->dwFlags & FLAG_BIGENDIAN); HFILEBYREF2XSCM(&phTmp->xSCM, phFile);
// API transfer
UPDATE_Lc((UINT8)(GetSCMBufferLength(&phTmp->xSCM)-5)); dwOut = MAX_APDU; dwRet = SCWTransmit(hCard, abCAPDU, (DWORD)GetSCMBufferLength(&phTmp->xSCM), abRAPDU, &dwOut);
if (dwRet == 0) { // Return code UnMarshaling
ret = ExtractSCODE(phTmp, abRAPDU, dwOut); } else ret = (SCODE)dwRet;
// Parameters UnMarshaling
if (ret == S_OK) { if (phFile) *phFile = XSCM2HFILE(&phTmp->xSCM); }
} __except(EXCEPTION_EXECUTE_HANDLER) {
switch(GetExceptionCode()) { case STATUS_INVALID_PARAM: ret = SCW_E_INVALIDPARAM; break;
case STATUS_INSUFFICIENT_MEM: ret = SCW_E_CANTMARSHAL; break;
case STATUS_INTERNAL_ERROR: ret = SCARD_F_INTERNAL_ERROR; break;
default: ret = SCARD_F_UNKNOWN_ERROR; } }
return ret; }
SCODE WINAPI hScwEnumFile(SCARDHANDLE hCard, WCSTR directoryName, UINT16 *fileCookie, WSTR fileName, TCOUNT fileNameLength) { SCODE ret; DWORD dwOut, dwRet; BYTE abCAPDU[5+MAX_APDU]; BYTE abRAPDU[MAX_APDU]; LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
LOG_BEGIN_PROXY(hScwEnumFile);
// Marshaling
__try {
if (phTmp == NULL) RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
if ((phTmp->dwFlags & FLAG_ISPROXY) == 0) return SCW_E_NOTIMPLEMENTED;
InitXSCM(phTmp, abCAPDU, phTmp->bResLen); CLA(0x00); INS(phTmp->byINS); P1(3); P2(15); Lc(0); UINT82XSCM(&phTmp->xSCM, 3, TYPE_NOTYPE_COUNT); // Number of parameters
String2XSCM(&phTmp->xSCM, directoryName, phTmp->dwFlags & FLAG_BIGENDIAN); UINT16BYREF2XSCM(&phTmp->xSCM, fileCookie, phTmp->dwFlags & FLAG_BIGENDIAN); StringOut2XSCM(&phTmp->xSCM, fileName, fileNameLength, phTmp->dwFlags & FLAG_BIGENDIAN);
// API transfer
UPDATE_Lc((UINT8)(GetSCMBufferLength(&phTmp->xSCM)-5)); dwOut = MAX_APDU; dwRet = SCWTransmit(hCard, abCAPDU, (DWORD)GetSCMBufferLength(&phTmp->xSCM), abRAPDU, &dwOut);
if (dwRet == 0) { // Return code UnMarshaling
ret = ExtractSCODE(phTmp, abRAPDU, dwOut); } else ret = (SCODE)dwRet;
// Parameters UnMarshaling
if (ret == S_OK) { WCSTR wsz; UINT8 len;
*fileCookie = XSCM2UINT16(&phTmp->xSCM, phTmp->dwFlags & FLAG_BIGENDIAN); wsz = XSCM2String(&phTmp->xSCM, &len, phTmp->dwFlags & FLAG_BIGENDIAN); if (len > fileNameLength) ret = SCW_E_BUFFERTOOSMALL; else wcscpy(fileName, wsz); }
} __except(EXCEPTION_EXECUTE_HANDLER) {
switch(GetExceptionCode()) { case STATUS_INVALID_PARAM: ret = SCW_E_INVALIDPARAM; break;
case STATUS_INSUFFICIENT_MEM: ret = SCW_E_CANTMARSHAL; break;
case STATUS_INTERNAL_ERROR: ret = SCARD_F_INTERNAL_ERROR; break;
default: ret = SCARD_F_UNKNOWN_ERROR; } }
return ret; }
SCODE WINAPI hScwCreateDirectory(SCARDHANDLE hCard, WCSTR fileName, WCSTR aclFileName) { SCODE ret; DWORD dwOut, dwRet; BYTE abCAPDU[5+MAX_APDU]; BYTE abRAPDU[MAX_APDU]; LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
LOG_BEGIN_PROXY(hScwCreateDirectory); // Marshaling
__try {
if (phTmp == NULL) RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
if ((phTmp->dwFlags & FLAG_ISPROXY) == 0) return SCW_E_NOTIMPLEMENTED;
InitXSCM(phTmp, abCAPDU, phTmp->bResLen); CLA(0x00); INS(phTmp->byINS); P1(3); P2(16); Lc(0); UINT82XSCM(&phTmp->xSCM, 2, TYPE_NOTYPE_COUNT); // Number of parameters
String2XSCM(&phTmp->xSCM, fileName, phTmp->dwFlags & FLAG_BIGENDIAN); String2XSCM(&phTmp->xSCM, aclFileName, phTmp->dwFlags & FLAG_BIGENDIAN);
// API transfer
UPDATE_Lc((UINT8)(GetSCMBufferLength(&phTmp->xSCM)-5)); dwOut = MAX_APDU; dwRet = SCWTransmit(hCard, abCAPDU, (DWORD)GetSCMBufferLength(&phTmp->xSCM), abRAPDU, &dwOut);
if (dwRet == 0) { // Return code UnMarshaling
ret = ExtractSCODE(phTmp, abRAPDU, dwOut); } else ret = (SCODE)dwRet;
// Parameters UnMarshaling
if (ret == S_OK) { }
} __except(EXCEPTION_EXECUTE_HANDLER) {
switch(GetExceptionCode()) { case STATUS_INVALID_PARAM: ret = SCW_E_INVALIDPARAM; break;
case STATUS_INSUFFICIENT_MEM: ret = SCW_E_CANTMARSHAL; break;
case STATUS_INTERNAL_ERROR: ret = SCARD_F_INTERNAL_ERROR; break;
default: ret = SCARD_F_UNKNOWN_ERROR; } }
return ret; }
SCODE WINAPI hScwSetDispatchTable(SCARDHANDLE hCard, WCSTR wszFileName) { SCODE ret; DWORD dwOut, dwRet; BYTE abCAPDU[5+MAX_APDU]; BYTE abRAPDU[MAX_APDU]; LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
LOG_BEGIN_PROXY(hScwSetDispatchTable);
// Marshaling
__try {
if (phTmp == NULL) RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
if ((phTmp->dwFlags & FLAG_ISPROXY) == 0) return SCW_E_NOTIMPLEMENTED;
InitXSCM(phTmp, abCAPDU, phTmp->bResLen); CLA(0x00); INS(phTmp->byINS); P1(3); P2(17); Lc(0); UINT82XSCM(&phTmp->xSCM, 1, TYPE_NOTYPE_COUNT); // Number of parameters
String2XSCM(&phTmp->xSCM, wszFileName, phTmp->dwFlags & FLAG_BIGENDIAN);
// API transfer
UPDATE_Lc((UINT8)(GetSCMBufferLength(&phTmp->xSCM)-5)); dwOut = MAX_APDU; dwRet = SCWTransmit(hCard, abCAPDU, (DWORD)GetSCMBufferLength(&phTmp->xSCM), abRAPDU, &dwOut);
if (dwRet == 0) { // Return code UnMarshaling
ret = ExtractSCODE(phTmp, abRAPDU, dwOut); } else ret = (SCODE)dwRet;
// Parameters UnMarshaling
if (ret == S_OK) { }
} __except(EXCEPTION_EXECUTE_HANDLER) {
switch(GetExceptionCode()) { case STATUS_INVALID_PARAM: ret = SCW_E_INVALIDPARAM; break;
case STATUS_INSUFFICIENT_MEM: ret = SCW_E_CANTMARSHAL; break;
case STATUS_INTERNAL_ERROR: ret = SCARD_F_INTERNAL_ERROR; break;
default: ret = SCARD_F_UNKNOWN_ERROR; } }
return ret; }
/*
** Cryptography */
SCODE WINAPI hScwCryptoInitialize(SCARDHANDLE hCard, BYTE mechanism, BYTE *key) { SCODE ret; DWORD dwOut, dwRet; BYTE abCAPDU[5+MAX_APDU]; BYTE abRAPDU[MAX_APDU]; TCOUNT len = 0; LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
LOG_BEGIN_PROXY(hScwCryptoInitialize);
// Marshaling
__try {
if (phTmp == NULL) RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
if ((phTmp->dwFlags & FLAG_ISPROXY) == 0) return SCW_E_NOTIMPLEMENTED;
InitXSCM(phTmp, abCAPDU, phTmp->bResLen); CLA(0x00); INS(phTmp->byINS); P1(5); P2(1); Lc(0); UINT82XSCM(&phTmp->xSCM, 2, TYPE_NOTYPE_COUNT); // Number of parameters
UINT82XSCM(&phTmp->xSCM, mechanism, TYPE_TYPED);
if (key) len = 2 + key[1]; // T+L+V
ByteArray2XSCM(&phTmp->xSCM, key, len);
// API transfer
UPDATE_Lc((UINT8)(GetSCMBufferLength(&phTmp->xSCM)-5)); dwOut = MAX_APDU; dwRet = SCWTransmit(hCard, abCAPDU, (DWORD)GetSCMBufferLength(&phTmp->xSCM), abRAPDU, &dwOut);
if (dwRet == 0) { // Return code UnMarshaling
ret = ExtractSCODE(phTmp, abRAPDU, dwOut); } else ret = (SCODE)dwRet;
// Parameters UnMarshaling
if (ret == S_OK) { phTmp->byCryptoM = mechanism; // Store the last mechanism for 1024 hack
}
} __except(EXCEPTION_EXECUTE_HANDLER) {
switch(GetExceptionCode()) { case STATUS_INVALID_PARAM: ret = SCW_E_INVALIDPARAM; break;
case STATUS_INSUFFICIENT_MEM: ret = SCW_E_CANTMARSHAL; break;
case STATUS_INTERNAL_ERROR: ret = SCARD_F_INTERNAL_ERROR; break;
default: ret = SCARD_F_UNKNOWN_ERROR; } }
return ret; }
SCODE WINAPI hScwCryptoAction(SCARDHANDLE hCard, BYTE *dataIn, TCOUNT dataInLength, BYTE *dataOut, TCOUNT *dataOutLength) { BOOL fHack = FALSE; SCODE ret; DWORD dwOut, dwRet; BYTE abCAPDU[5+MAX_APDU]; BYTE abRAPDU[MAX_APDU]; LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
LOG_BEGIN_PROXY(hScwCryptoAction);
// Marshaling
__try {
if (phTmp == NULL) RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
if ((phTmp->dwFlags & FLAG_ISPROXY) == 0) return SCW_E_NOTIMPLEMENTED;
InitXSCM(phTmp, abCAPDU, phTmp->bResLen); CLA(0x00); INS(phTmp->byINS); if ((((phTmp->byCryptoM & CM_CRYPTO_NAME) == CM_RSA) || ((phTmp->byCryptoM & CM_CRYPTO_NAME) == CM_RSA_CRT)) && ((phTmp->byCryptoM & CM_DATA_INFILE) != CM_DATA_INFILE)) { // Hack for 1024 RSA
P1(0xFE); P2(0); Lc(0); ByteArray2XSCM(&phTmp->xSCM, dataIn, dataInLength); if (dataOutLength == NULL) RaiseException(STATUS_INVALID_PARAM, 0, 0, 0); abCAPDU[5] = *dataOutLength; fHack = TRUE; } else { P1(5); P2(2); Lc(0); UINT82XSCM(&phTmp->xSCM, 3, TYPE_NOTYPE_COUNT); // Number of parameters
ByteArray2XSCM(&phTmp->xSCM, dataIn, dataInLength); ByteArrayOut2XSCM(&phTmp->xSCM, dataOut, (TCOUNT)(dataOutLength == 0 ? 0 : *dataOutLength)); UINT8BYREF2XSCM(&phTmp->xSCM, dataOutLength); }
// API transfer
UPDATE_Lc((UINT8)(GetSCMBufferLength(&phTmp->xSCM)-5)); dwOut = MAX_APDU; dwRet = SCWTransmit(hCard, abCAPDU, (DWORD)GetSCMBufferLength(&phTmp->xSCM), abRAPDU, &dwOut);
if (dwRet == 0) { // Return code UnMarshaling
ret = ExtractSCODE(phTmp, abRAPDU, dwOut); } else ret = (SCODE)dwRet;
// Parameters UnMarshaling
if (ret == S_OK) { BYTE *pb; TCOUNT len;
len = XSCM2ByteArray(&phTmp->xSCM, &pb); if (len > *dataOutLength) ret = SCW_E_BUFFERTOOSMALL; else { memcpy(dataOut, pb, len); if (fHack) *dataOutLength = len; else *dataOutLength = XSCM2UINT8(&phTmp->xSCM); } }
} __except(EXCEPTION_EXECUTE_HANDLER) {
switch(GetExceptionCode()) { case STATUS_INVALID_PARAM: ret = SCW_E_INVALIDPARAM; break;
case STATUS_INSUFFICIENT_MEM: ret = SCW_E_CANTMARSHAL; break;
case STATUS_INTERNAL_ERROR: ret = SCARD_F_INTERNAL_ERROR; break;
default: ret = SCARD_F_UNKNOWN_ERROR; } }
return ret; }
SCODE WINAPI hScwCryptoUpdate(SCARDHANDLE hCard, BYTE *dataIn, TCOUNT dataInLength) { SCODE ret; DWORD dwOut, dwRet; BYTE abCAPDU[5+MAX_APDU]; BYTE abRAPDU[MAX_APDU]; LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
LOG_BEGIN_PROXY(hScwCryptoUpdate);
// Marshaling
__try {
if (phTmp == NULL) RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
if ((phTmp->dwFlags & FLAG_ISPROXY) == 0) return SCW_E_NOTIMPLEMENTED;
InitXSCM(phTmp, abCAPDU, phTmp->bResLen); CLA(0x00); INS(phTmp->byINS); P1(5); P2(3); Lc(0); UINT82XSCM(&phTmp->xSCM, 1, TYPE_NOTYPE_COUNT); // Number of parameters
ByteArray2XSCM(&phTmp->xSCM, dataIn, dataInLength);
// API transfer
UPDATE_Lc((UINT8)(GetSCMBufferLength(&phTmp->xSCM)-5)); dwOut = MAX_APDU; dwRet = SCWTransmit(hCard, abCAPDU, (DWORD)GetSCMBufferLength(&phTmp->xSCM), abRAPDU, &dwOut);
if (dwRet == 0) { // Return code UnMarshaling
ret = ExtractSCODE(phTmp, abRAPDU, dwOut); } else ret = (SCODE)dwRet;
// Parameters UnMarshaling
if (ret == S_OK) { }
} __except(EXCEPTION_EXECUTE_HANDLER) {
switch(GetExceptionCode()) { case STATUS_INVALID_PARAM: ret = SCW_E_INVALIDPARAM; break;
case STATUS_INSUFFICIENT_MEM: ret = SCW_E_CANTMARSHAL; break;
case STATUS_INTERNAL_ERROR: ret = SCARD_F_INTERNAL_ERROR; break;
default: ret = SCARD_F_UNKNOWN_ERROR; } }
return ret; }
SCODE WINAPI hScwCryptoFinalize(SCARDHANDLE hCard, BYTE *dataOut, TCOUNT *dataOutLength) { SCODE ret; DWORD dwOut, dwRet; BYTE abCAPDU[5+MAX_APDU]; BYTE abRAPDU[MAX_APDU]; LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
LOG_BEGIN_PROXY(hScwCryptoFinalize);
// Marshaling
__try {
if (phTmp == NULL) RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
if ((phTmp->dwFlags & FLAG_ISPROXY) == 0) return SCW_E_NOTIMPLEMENTED;
InitXSCM(phTmp, abCAPDU, phTmp->bResLen); CLA(0x00); INS(phTmp->byINS); P1(5); P2(4); Lc(0); UINT82XSCM(&phTmp->xSCM, 2, TYPE_NOTYPE_COUNT); // Number of parameters
ByteArrayOut2XSCM(&phTmp->xSCM, dataOut, (TCOUNT)(dataOutLength == 0 ? 0 : *dataOutLength)); UINT8BYREF2XSCM(&phTmp->xSCM, dataOutLength);
// API transfer
UPDATE_Lc((UINT8)(GetSCMBufferLength(&phTmp->xSCM)-5)); dwOut = MAX_APDU; dwRet = SCWTransmit(hCard, abCAPDU, (DWORD)GetSCMBufferLength(&phTmp->xSCM), abRAPDU, &dwOut);
if (dwRet == 0) { // Return code UnMarshaling
ret = ExtractSCODE(phTmp, abRAPDU, dwOut); } else ret = (SCODE)dwRet;
// Parameters UnMarshaling
if (ret == S_OK) { BYTE *pb; TCOUNT len;
len = XSCM2ByteArray(&phTmp->xSCM, &pb); if (len > *dataOutLength) ret = SCW_E_BUFFERTOOSMALL; else { memcpy(dataOut, pb, len); *dataOutLength = XSCM2UINT8(&phTmp->xSCM); } }
} __except(EXCEPTION_EXECUTE_HANDLER) {
switch(GetExceptionCode()) { case STATUS_INVALID_PARAM: ret = SCW_E_INVALIDPARAM; break;
case STATUS_INSUFFICIENT_MEM: ret = SCW_E_CANTMARSHAL; break;
case STATUS_INTERNAL_ERROR: ret = SCARD_F_INTERNAL_ERROR; break;
default: ret = SCARD_F_UNKNOWN_ERROR; } }
return ret; }
SCODE WINAPI hScwGenerateRandom(SCARDHANDLE hCard, BYTE *dataOut, TCOUNT dataOutLength) { SCODE ret; DWORD dwOut, dwRet; BYTE abCAPDU[5+MAX_APDU]; BYTE abRAPDU[MAX_APDU]; LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
LOG_BEGIN_PROXY(hScwGenerateRandom);
// Marshaling
__try {
if (phTmp == NULL) RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
if ((phTmp->dwFlags & FLAG_ISPROXY) == 0) return SCW_E_NOTIMPLEMENTED;
InitXSCM(phTmp, abCAPDU, phTmp->bResLen); CLA(0x00); INS(phTmp->byINS); P1(5); P2(5); Lc(0); UINT82XSCM(&phTmp->xSCM, 2, TYPE_NOTYPE_COUNT); // Number of parameters
ByteArrayOut2XSCM(&phTmp->xSCM, dataOut, dataOutLength); UINT8BYREF2XSCM(&phTmp->xSCM, &dataOutLength);
// API transfer
UPDATE_Lc((UINT8)(GetSCMBufferLength(&phTmp->xSCM)-5)); dwOut = MAX_APDU; dwRet = SCWTransmit(hCard, abCAPDU, (DWORD)GetSCMBufferLength(&phTmp->xSCM), abRAPDU, &dwOut);
if (dwRet == 0) { // Return code UnMarshaling
ret = ExtractSCODE(phTmp, abRAPDU, dwOut); } else ret = (SCODE)dwRet;
// Parameters UnMarshaling
if (ret == S_OK) { BYTE *pb; TCOUNT len;
len = XSCM2ByteArray(&phTmp->xSCM, &pb); if (len != dataOutLength) ret = SCW_E_BUFFERTOOSMALL; else memcpy(dataOut, pb, len); }
} __except(EXCEPTION_EXECUTE_HANDLER) {
switch(GetExceptionCode()) { case STATUS_INVALID_PARAM: ret = SCW_E_INVALIDPARAM; break;
case STATUS_INSUFFICIENT_MEM: ret = SCW_E_CANTMARSHAL; break;
case STATUS_INTERNAL_ERROR: ret = SCARD_F_INTERNAL_ERROR; break;
default: ret = SCARD_F_UNKNOWN_ERROR; } }
return ret; }
/*
** Runtime Environment */
SCODE WINAPI hScwRTEExecute(SCARDHANDLE hCard, WCSTR wszCodeFileName, WCSTR wszDataFileName, UINT8 bRestart) { SCODE ret; DWORD dwOut, dwRet; BYTE abCAPDU[5+MAX_APDU]; BYTE abRAPDU[MAX_APDU]; LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
LOG_BEGIN_PROXY(hScwRTEExecute);
// Marshaling
__try {
if (phTmp == NULL) RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
if ((phTmp->dwFlags & FLAG_ISPROXY) == 0) return SCW_E_NOTIMPLEMENTED;
InitXSCM(phTmp, abCAPDU, phTmp->bResLen); CLA(0x00); INS(phTmp->byINS); P1(1); P2(1); Lc(0); UINT82XSCM(&phTmp->xSCM, 3, TYPE_NOTYPE_COUNT); // Number of parameters
String2XSCM(&phTmp->xSCM, wszCodeFileName, phTmp->dwFlags & FLAG_BIGENDIAN); String2XSCM(&phTmp->xSCM, wszDataFileName, phTmp->dwFlags & FLAG_BIGENDIAN); UINT82XSCM(&phTmp->xSCM, bRestart, TYPE_TYPED);
// API transfer
UPDATE_Lc((UINT8)(GetSCMBufferLength(&phTmp->xSCM)-5)); dwOut = MAX_APDU; dwRet = SCWTransmit(hCard, abCAPDU, (DWORD)GetSCMBufferLength(&phTmp->xSCM), abRAPDU, &dwOut);
if (dwRet == 0) { // Return code UnMarshaling
ret = ExtractSCODE(phTmp, abRAPDU, dwOut); } else ret = (SCODE)dwRet;
// Parameters UnMarshaling
if (ret == S_OK) { }
} __except(EXCEPTION_EXECUTE_HANDLER) {
switch(GetExceptionCode()) { case STATUS_INVALID_PARAM: ret = SCW_E_INVALIDPARAM; break;
case STATUS_INSUFFICIENT_MEM: ret = SCW_E_CANTMARSHAL; break;
case STATUS_INTERNAL_ERROR: ret = SCARD_F_INTERNAL_ERROR; break;
default: ret = SCARD_F_UNKNOWN_ERROR; } }
return ret; }
/*
ScwExecute: I-: lpxHdr (points to 4 bytes (CLA, INS, P1, P2)) I-: InBuf (Incoming data from card's perspective (NULL -> no data in)) I-: InBufLen (length of data pointed by InBuf) -O: OutBuf (Buffer that will receive the R-APDU (NULL -> no expected data)) IO: pOutBufLen (I -> Size of OutBuf, O -> Number of bytes written in OutBuf) -O: pwSW (Card Status Word) */ SCODE WINAPI hScwExecute(SCARDHANDLE hCard, LPISO_HEADER lpxHdr, BYTE *InBuf, TCOUNT InBufLen, BYTE *OutBuf, TCOUNT *pOutBufLen, UINT16 *pwSW) { SCODE ret; DWORD dwIn, dwOut, dwRet; BYTE abCAPDU[5+MAX_APDU]; BYTE abRAPDU[MAX_APDU]; LPMYSCARDHANDLE phTmp = (LPMYSCARDHANDLE)hCard;
LOG_BEGIN_PROXY(hScwExecute);
__try {
if ((lpxHdr == NULL) || (pwSW == NULL) || ((OutBuf != NULL) && (pOutBufLen == NULL))) RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
if (phTmp == NULL) RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
abCAPDU[0] = lpxHdr->CLA; abCAPDU[1] = lpxHdr->INS; abCAPDU[2] = lpxHdr->P1; abCAPDU[3] = lpxHdr->P2; if ((InBuf != NULL) && (InBufLen != 0)) { abCAPDU[4] = (BYTE)InBufLen; memcpy(abCAPDU+5, InBuf, InBufLen); dwIn = 5 + InBufLen;
// We don't care about out data yet
} else { // No in data. How much data out then?
dwIn = 5; if (OutBuf == NULL) // No data out either
{ abCAPDU[4] = 0; if (phTmp->dwProtocol == SCARD_PROTOCOL_T0) dwIn = 4; // To indicate a case 1 command
} else abCAPDU[4] = (BYTE)(*pOutBufLen); }
// API transfer
dwOut = MAX_APDU; dwRet = SCWTransmit(hCard, abCAPDU, dwIn, abRAPDU, &dwOut);
if (dwRet == 0) { if (dwOut < 2) ret = SCARD_F_INTERNAL_ERROR; else { *pwSW = MAKEWORD(abRAPDU[dwOut-1], abRAPDU[dwOut-2]); dwOut -= 2;
ret = 0; if (OutBuf != NULL) { if (dwOut <= (DWORD)(*pOutBufLen)) { memcpy(OutBuf, abRAPDU, dwOut); *pOutBufLen = (TCOUNT)dwOut; } else ret = SCW_E_BUFFERTOOSMALL; } } } else ret = (SCODE)dwRet;
} __except(EXCEPTION_EXECUTE_HANDLER) {
switch(GetExceptionCode()) { case STATUS_INVALID_PARAM: ret = SCW_E_INVALIDPARAM; break;
case STATUS_INSUFFICIENT_MEM: ret = SCW_E_CANTMARSHAL; break;
case STATUS_INTERNAL_ERROR: ret = SCARD_F_INTERNAL_ERROR; break;
default: ret = SCARD_F_UNKNOWN_ERROR; } }
return ret; }
static SCODE ExtractSCODE(LPMYSCARDHANDLE phTmp, LPCBYTE abRAPDU, DWORD dwOut) { if (FLAG2VERSION(phTmp->dwFlags) == VERSION_1_0) { if ((dwOut < 2) || (abRAPDU[dwOut-2] != 0x90) || (abRAPDU[dwOut-1] != 0x00)) RaiseException(STATUS_INTERNAL_ERROR, 0, 0, 0);
InitXSCM(phTmp, abRAPDU, (WORD)(dwOut-2)); // Doesn't take SW into account
return XSCM2SCODE(&phTmp->xSCM); } else if (FLAG2VERSION(phTmp->dwFlags) == VERSION_1_1) { if ((dwOut < 2) || (abRAPDU[dwOut-2] != 0x90)) RaiseException(STATUS_INTERNAL_ERROR, 0, 0, 0);
InitXSCM(phTmp, abRAPDU, (WORD)(dwOut-2)); // Doesn't take SW into account
return MAKESCODE(abRAPDU[dwOut-1]); } else RaiseException(STATUS_INTERNAL_ERROR, 0, 0, 0);
return SCW_S_OK; // to please the compiler
}
|