|
|
@ -48,7 +48,7 @@ CDllDirectory::CDllDirectory()
|
|
|
|
|
|
|
|
|
|
|
|
CDllDirectory::~CDllDirectory()
|
|
|
|
CDllDirectory::~CDllDirectory()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
// TODO: Delete m_ChunkCache and m_Entries when !ChunksOwnsPointers
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
std::string CDllDirectory::getClassName()
|
|
|
|
std::string CDllDirectory::getClassName()
|
|
|
@ -57,18 +57,103 @@ std::string CDllDirectory::getClassName()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CDllDirectory::toString(std::ostream &ostream, const std::string &pad)
|
|
|
|
void CDllDirectory::toString(std::ostream &ostream, const std::string &pad)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (ChunksOwnsPointers)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
CStorageContainer::toString(ostream, pad);
|
|
|
|
CStorageContainer::toString(ostream, pad);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
ostream << "(" << getClassName() << ") [" << Chunks.size() << "] PARSED { ";
|
|
|
|
|
|
|
|
std::string padpad = pad + "\t";
|
|
|
|
|
|
|
|
sint i = 0;
|
|
|
|
|
|
|
|
for (TStorageObjectContainer::const_iterator it = m_ChunkCache.begin(), end = m_ChunkCache.end(); it != end; ++it)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
uint16 id = it->first;
|
|
|
|
|
|
|
|
switch (id)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
case 0x2038:
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
uint subi = 0;
|
|
|
|
|
|
|
|
for (std::vector<CDllEntry *>::iterator subit = m_Entries.begin(), subend = m_Entries.end(); subit != subend; ++subit)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
ostream << "\n" << pad << "Entries[" << subi << "]: ";
|
|
|
|
|
|
|
|
(*subit)->toString(ostream, padpad);
|
|
|
|
|
|
|
|
++subi;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
|
|
std::stringstream ss;
|
|
|
|
|
|
|
|
ss << std::hex << std::setfill('0');
|
|
|
|
|
|
|
|
ss << std::setw(4) << it->first;
|
|
|
|
|
|
|
|
ostream << "\n" << pad << "0x" << ss.str() << ": ";
|
|
|
|
|
|
|
|
it->second->toString(ostream, padpad);
|
|
|
|
|
|
|
|
++i;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
ostream << "} ";
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CDllDirectory::parse(uint16 version, TParseLevel level)
|
|
|
|
void CDllDirectory::parse(uint16 version, TParseLevel level)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
if (level & PARSE_INTERNAL)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// Ensure not yet parsed
|
|
|
|
|
|
|
|
nlassert(m_ChunkCache.empty());
|
|
|
|
|
|
|
|
nlassert(m_Entries.empty());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Parse entries first
|
|
|
|
CStorageContainer::parse(version, level);
|
|
|
|
CStorageContainer::parse(version, level);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Initialize
|
|
|
|
|
|
|
|
m_ParseVersion = version;
|
|
|
|
|
|
|
|
uint16 lastCached = 0xFFFF;
|
|
|
|
|
|
|
|
bool parsedDllEntry = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Parse chunks
|
|
|
|
|
|
|
|
for (TStorageObjectContainer::iterator it = Chunks.begin(), end = Chunks.end(); it != end; ++it)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
uint16 id = it->first;
|
|
|
|
|
|
|
|
switch (id)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
case 0x2038: // DllEntry
|
|
|
|
|
|
|
|
if (parsedDllEntry && (lastCached != id))
|
|
|
|
|
|
|
|
throw EStorageParse(); // There were chunks inbetween
|
|
|
|
|
|
|
|
if (!parsedDllEntry)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
m_ChunkCache.push_back(TStorageObjectWithId(id, NULL)); // Dummy entry to know the location
|
|
|
|
|
|
|
|
lastCached = id;
|
|
|
|
|
|
|
|
parsedDllEntry = true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
m_Entries.push_back(static_cast<CDllEntry *>(it->second));
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
|
|
m_ChunkCache.push_back(*it); // Dummy entry to know the location
|
|
|
|
|
|
|
|
lastCached = id;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Now ownership of the pointers lies in m_ChunkCache and m_Entries
|
|
|
|
|
|
|
|
ChunksOwnsPointers = false;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CDllDirectory::build(uint16 version)
|
|
|
|
void CDllDirectory::build(uint16 version)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
// TODO: Set up the Chunks list, when (CDllEntry::ID, NULL) is found write out all of the entries.
|
|
|
|
|
|
|
|
// Build the entries last
|
|
|
|
CStorageContainer::build(version);
|
|
|
|
CStorageContainer::build(version);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// NOTE: Ownership remains with m_ChunkCache and m_Entries
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const CDllEntry *CDllDirectory::get(std::vector<CDllEntry *>::size_type idx) const
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return m_Entries[idx];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
IStorageObject *CDllDirectory::createChunkById(uint16 id, bool container)
|
|
|
|
IStorageObject *CDllDirectory::createChunkById(uint16 id, bool container)
|
|
|
@ -92,7 +177,7 @@ IStorageObject *CDllDirectory::createChunkById(uint16 id, bool container)
|
|
|
|
return CStorageContainer::createChunkById(id, container);
|
|
|
|
return CStorageContainer::createChunkById(id, container);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CDllEntry::CDllEntry()
|
|
|
|
CDllEntry::CDllEntry() : m_DllDescription(NULL), m_DllFilename(NULL)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -108,18 +193,38 @@ std::string CDllEntry::getClassName()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CDllEntry::toString(std::ostream &ostream, const std::string &pad)
|
|
|
|
void CDllEntry::toString(std::ostream &ostream, const std::string &pad)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (m_DllDescription && m_DllFilename)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
ostream << "(" << getClassName() << ") [" << Chunks.size() << "] PARSED { ";
|
|
|
|
|
|
|
|
std::string padpad = pad + "\t";
|
|
|
|
|
|
|
|
ostream << "\n" << pad << "DllDescription: " << m_DllDescription->Value.toUtf8();
|
|
|
|
|
|
|
|
ostream << "\n" << pad << "DllFilename: " << m_DllFilename->Value.toUtf8();
|
|
|
|
|
|
|
|
ostream << "} ";
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
CStorageContainer::toString(ostream, pad);
|
|
|
|
CStorageContainer::toString(ostream, pad);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CDllEntry::parse(uint16 version, TParseLevel level)
|
|
|
|
void CDllEntry::parse(uint16 version, TParseLevel level)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
CStorageContainer::parse(version, level);
|
|
|
|
// CStorageContainer::parse(version, level);
|
|
|
|
|
|
|
|
nlassert(Chunks.size() == 2);
|
|
|
|
|
|
|
|
TStorageObjectContainer::iterator it = Chunks.begin();
|
|
|
|
|
|
|
|
nlassert(it->first == 0x2039); // DllDescription
|
|
|
|
|
|
|
|
m_DllDescription = static_cast<CStorageValue<ucstring> *>(it->second);
|
|
|
|
|
|
|
|
++it;
|
|
|
|
|
|
|
|
nlassert(it->first == 0x2037); // DllFilename
|
|
|
|
|
|
|
|
m_DllFilename = static_cast<CStorageValue<ucstring> *>(it->second);
|
|
|
|
|
|
|
|
// ++it;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CDllEntry::build(uint16 version)
|
|
|
|
void CDllEntry::build(uint16 version)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
CStorageContainer::build(version);
|
|
|
|
// Nothing to do here!
|
|
|
|
|
|
|
|
// CStorageContainer::build(version);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
IStorageObject *CDllEntry::createChunkById(uint16 id, bool container)
|
|
|
|
IStorageObject *CDllEntry::createChunkById(uint16 id, bool container)
|
|
|
|