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.
 
 
 
 
 
 

2492 lines
67 KiB

/*
** 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
}