Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

298 lines
6.8 KiB

// ObjectInfoFile.cpp: implementation of the CObjectInfoFile class.
//
// (c) Copyright Schlumberger Technology Corp., unpublished work, created
// 1999. This computer program includes Confidential, Proprietary
// Information and is a Trade Secret of Schlumberger Technology Corp. All
// use, disclosure, and/or reproduction is prohibited unless authorized
// in writing. All Rights Reserved.
//////////////////////////////////////////////////////////////////////
#include "cciCard.h"
#include "SymbolTable.h"
#include "ObjectInfoFile.h"
using std::string;
using namespace cci;
using namespace iop;
CObjectInfoFile::CObjectInfoFile(CSmartCard &rSmartCard,
string const &Path,
ObjectAccess oa)
: m_oa(oa),
m_Path(Path),
m_SymbolTable(rSmartCard, Path, ObjMasterBlkSize),
m_rSmartCard(rSmartCard)
{
}
void CObjectInfoFile::Reset()
{
BYTE bMasterBlk[ObjMasterBlkSize];
memset(bMasterBlk,0,ObjMasterBlkSize);
m_rSmartCard.Select(m_Path.c_str());
m_rSmartCard.WriteBinary(0, ObjMasterBlkSize, bMasterBlk);
m_bDefaultContainer = 0;
m_bFirstContainer = 0;
m_bFirstCertificate = 0;
m_bFirstPublicKey = 0;
m_bFirstPrivateKey = 0;
m_bFirstDataObject = 0;
m_SymbolTable.Reset();
}
void CObjectInfoFile::UpdateCache()
{
BYTE bMasterBlk[ObjMasterBlkSize];
m_rSmartCard.Select(m_Path.c_str());
m_rSmartCard.ReadBinary(0, ObjMasterBlkSize, bMasterBlk);
m_bDefaultContainer = bMasterBlk[ObjDefaultContainerLoc];
m_bFirstContainer = bMasterBlk[ObjFirstContainerLoc];
m_bFirstCertificate = bMasterBlk[ObjFirstCertificateLoc];
m_bFirstPublicKey = bMasterBlk[ObjFirstPublicKeyLoc];
m_bFirstPrivateKey = bMasterBlk[ObjFirstPrivateKeyLoc];
m_bFirstDataObject = bMasterBlk[ObjFirstDataObjectLoc];
}
ObjectAccess
CObjectInfoFile::AccessType() const
{
return m_oa;
}
void CObjectInfoFile::DefaultContainer(SymbolID bHandle)
{
m_rSmartCard.Select(m_Path.c_str());
m_rSmartCard.WriteBinary(ObjDefaultContainerLoc, 1, &bHandle);
m_bDefaultContainer = bHandle;
}
SymbolID CObjectInfoFile::AddSymbol(string aString)
{
return m_SymbolTable.Add(aString);
}
string CObjectInfoFile::FindSymbol(SymbolID sid)
{
return m_SymbolTable.Find(sid);
}
void CObjectInfoFile::RemoveSymbol(SymbolID sid)
{
m_SymbolTable.Remove(sid);
}
SymbolID CObjectInfoFile::FirstObject(ObjectType type) const
{
SymbolID sid;
switch(type)
{
case otContainerObject:
sid = m_bFirstContainer;
break;
case otCertificateObject:
sid = m_bFirstCertificate;
break;
case otPublicKeyObject:
sid = m_bFirstPublicKey;
break;
case otPrivateKeyObject:
sid = m_bFirstPrivateKey;
break;
case otDataObjectObject:
sid = m_bFirstDataObject;
break;
default:
throw cci::Exception(ccBadObjectType);
break;
}
return sid;
}
void CObjectInfoFile::FirstObject(ObjectType type, SymbolID bHandle)
{
unsigned short sLoc;
SymbolID *pbCachedValue;
switch(type) {
case otContainerObject:
sLoc = ObjFirstContainerLoc;
pbCachedValue = &m_bFirstContainer;
break;
case otCertificateObject:
sLoc = ObjFirstCertificateLoc;
pbCachedValue = &m_bFirstCertificate;
break;
case otPublicKeyObject:
sLoc = ObjFirstPublicKeyLoc;
pbCachedValue = &m_bFirstPublicKey;
break;
case otPrivateKeyObject:
sLoc = ObjFirstPrivateKeyLoc;
pbCachedValue = &m_bFirstPrivateKey;
break;
case otDataObjectObject:
sLoc = ObjFirstDataObjectLoc;
pbCachedValue = &m_bFirstDataObject;
break;
default:
throw cci::Exception(ccBadObjectType);
}
m_rSmartCard.Select(m_Path.c_str());
m_rSmartCard.WriteBinary(sLoc, 1, &bHandle);
*pbCachedValue = bHandle; // Update cache after successful write
}
SymbolID CObjectInfoFile::NextObject(SymbolID bHandle)
{
string ObjInfoRecord(m_SymbolTable.Find(bHandle));
if (!ObjInfoRecord.size())
throw cci::Exception(ccFormatError);
return static_cast<SymbolID>(ObjInfoRecord[0]);
}
void CObjectInfoFile::NextObject(SymbolID bHandle, SymbolID bHandleNext)
{
string ObjInfoRecord(m_SymbolTable.Find(bHandle));
if (!ObjInfoRecord.size())
throw cci::Exception(ccFormatError);
ObjInfoRecord[0] = bHandleNext;
m_SymbolTable.Replace(bHandle,ObjInfoRecord);
}
SymbolID CObjectInfoFile::AddObject(ObjectType type, unsigned short size)
{
string strTemp;
strTemp.resize(size+1);
SymbolID bHandle;
bHandle = m_SymbolTable.Add(strTemp, smExclusive);
// Add to end of list
SymbolID bLast = FirstObject(type);
if(!bLast) // No objects in list, add to head of list
{
FirstObject(type,bHandle);
}
else
{
// Search for the last object
SymbolID bLastNext = NextObject(bLast);
while(bLastNext) {
bLast = bLastNext;
bLastNext = NextObject(bLast);
}
NextObject(bLast,bHandle);
}
return bHandle;
}
void CObjectInfoFile::RemoveObject(ObjectType type, SymbolID bHandle)
{
if (FirstObject(type) == bHandle) // Remove from head of list
{
FirstObject(type,NextObject(bHandle));
}
else
{
// Remove from middle/end of list, search for the previous object
SymbolID bPrevNext, bPrevious = FirstObject(type);
while(bPrevious)
{
bPrevNext = NextObject(bPrevious);
if (bHandle == bPrevNext)
break;
bPrevious = bPrevNext;
}
if (!bPrevious)
throw cci::Exception(ccFormatError); // Object not linked
// through this list
NextObject(bPrevious,NextObject(bHandle));
}
m_SymbolTable.Remove(bHandle);
}
void CObjectInfoFile::ReadObject(SymbolID bHandle, BYTE* bData)
{
string ObjInfoRecord(m_SymbolTable.Find(bHandle));
string::size_type size = ObjInfoRecord.size();
if (!size)
throw cci::Exception(ccFormatError);
ObjInfoRecord.copy(reinterpret_cast<char*>(bData) , size - 1,
1); // Skip the leading byte.
}
void CObjectInfoFile::WriteObject(SymbolID bHandle, BYTE* bData)
{
string ObjInfoRecord(m_SymbolTable.Find(bHandle));
string::size_type size = ObjInfoRecord.size();
if (!size)
throw cci::Exception(ccFormatError);
ObjInfoRecord.resize(1);
ObjInfoRecord += string(reinterpret_cast<char *>(bData), size - 1);
m_SymbolTable.Replace(bHandle,ObjInfoRecord);
}
unsigned short CObjectInfoFile::TableSize()
{
return m_SymbolTable.TableSize();
}
unsigned short CObjectInfoFile::FreeSpace()
{
return m_SymbolTable.FreeSpace();
}