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.
336 lines
7.0 KiB
336 lines
7.0 KiB
#include "pch.h"
|
|
#pragma hdrstop
|
|
#include "modlist.h"
|
|
|
|
BOOL
|
|
CModuleList::FDumpToString (
|
|
OUT PSTR pszBuf,
|
|
IN OUT ULONG* pcchBuf) const
|
|
{
|
|
const_iterator iter;
|
|
const CModule* pMod;
|
|
ULONG cch;
|
|
ULONG cchIn;
|
|
BOOL fFirstTime;
|
|
|
|
Assert (this);
|
|
Assert (pcchBuf);
|
|
|
|
cch = 0;
|
|
cchIn = *pcchBuf;
|
|
|
|
for (iter = begin(), fFirstTime = TRUE; iter != end(); iter++)
|
|
{
|
|
if (!fFirstTime)
|
|
{
|
|
cch += 2;
|
|
if (pszBuf && (cch <= cchIn))
|
|
{
|
|
strcat (pszBuf, "->");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
fFirstTime = FALSE;
|
|
if (pszBuf && (cch <= cchIn))
|
|
{
|
|
*pszBuf = 0;
|
|
}
|
|
}
|
|
|
|
pMod = *iter;
|
|
Assert (pMod);
|
|
|
|
cch += strlen (pMod->m_pszFileName);
|
|
if (pszBuf && (cch <= cchIn))
|
|
{
|
|
strcat (pszBuf, pMod->m_pszFileName);
|
|
}
|
|
}
|
|
|
|
// If we ran out of room, erase the partial stuff we wrote.
|
|
//
|
|
if (pszBuf && cchIn && (cch > cchIn))
|
|
{
|
|
*pszBuf = 0;
|
|
}
|
|
|
|
*pcchBuf = cch;
|
|
return cch <= cchIn;
|
|
}
|
|
|
|
BOOL
|
|
CModuleList::FIsSameModuleListAs (
|
|
IN const CModuleList* pOtherList) const
|
|
{
|
|
UINT unThisSize;
|
|
UINT unOtherSize;
|
|
UINT cb;
|
|
|
|
Assert (this);
|
|
Assert (pOtherList);
|
|
|
|
unThisSize = this->size();
|
|
unOtherSize = pOtherList->size();
|
|
|
|
if ((0 == unThisSize) || (0 == unOtherSize) || (unThisSize != unOtherSize))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
// Sizes are non-zero and equal. Compare the data.
|
|
//
|
|
cb = (BYTE*)(end()) - (BYTE*)(begin());
|
|
Assert (cb == unThisSize * sizeof(CModule*));
|
|
|
|
return (0 == memcmp (
|
|
(BYTE*)(this->begin()),
|
|
(BYTE*)(pOtherList->begin()),
|
|
cb));
|
|
}
|
|
|
|
VOID
|
|
CModuleList::GrowBufferIfNeeded ()
|
|
{
|
|
if (m_Granularity && (size() == capacity()))
|
|
{
|
|
//fprintf(stderr, "growing module list buffer\n");
|
|
|
|
__try
|
|
{
|
|
reserve (size() + m_Granularity);
|
|
}
|
|
__except(EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
;
|
|
}
|
|
}
|
|
}
|
|
|
|
HRESULT
|
|
CModuleList::HrInsertModule (
|
|
IN const CModule* pMod,
|
|
IN DWORD dwFlags /* INS_FLAGS */)
|
|
{
|
|
HRESULT hr;
|
|
|
|
Assert (this);
|
|
Assert (pMod);
|
|
Assert (dwFlags);
|
|
Assert (dwFlags & (INS_ASSERT_IF_DUP | INS_IGNORE_IF_DUP));
|
|
Assert (!(dwFlags & (INS_SORTED | INS_NON_SORTED)));
|
|
Assert (dwFlags & (INS_APPEND | INS_INSERT));
|
|
|
|
if (FLinearFindModuleByPointer (pMod))
|
|
{
|
|
Assert (dwFlags & INS_IGNORE_IF_DUP);
|
|
return S_OK;
|
|
}
|
|
|
|
GrowBufferIfNeeded ();
|
|
|
|
__try
|
|
{
|
|
iterator InsertPosition = begin();
|
|
|
|
if (dwFlags & INS_APPEND)
|
|
{
|
|
InsertPosition = end();
|
|
}
|
|
|
|
insert (InsertPosition, (CModule*)pMod);
|
|
hr = S_OK;
|
|
}
|
|
__except(EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
CModuleList::HrInsertNewModule (
|
|
IN PCSTR pszFileName,
|
|
IN ULONG cbFileSize,
|
|
IN DWORD dwFlags, /* INS_FLAGS */
|
|
OUT CModule** ppMod)
|
|
{
|
|
HRESULT hr;
|
|
iterator InsertPosition = NULL;
|
|
CModule* pMod;
|
|
CHAR szLowerCaseFileName [MAX_PATH];
|
|
|
|
Assert (dwFlags);
|
|
Assert (dwFlags & (INS_ASSERT_IF_DUP | INS_IGNORE_IF_DUP));
|
|
Assert (dwFlags & INS_SORTED);
|
|
Assert (!(dwFlags & (INS_APPEND | INS_INSERT)));
|
|
|
|
GrowBufferIfNeeded ();
|
|
|
|
hr = S_OK;
|
|
|
|
strcpy (szLowerCaseFileName, pszFileName);
|
|
_strlwr (szLowerCaseFileName);
|
|
|
|
pMod = PBinarySearchModuleByName (szLowerCaseFileName, &InsertPosition);
|
|
|
|
if (!pMod)
|
|
{
|
|
Assert (!PLinearFindModuleByName (szLowerCaseFileName));
|
|
|
|
hr = CModule::HrCreateInstance (szLowerCaseFileName, cbFileSize, &pMod);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
if (dwFlags & INS_NON_SORTED)
|
|
{
|
|
InsertPosition = (dwFlags & INS_APPEND) ? end() : begin();
|
|
}
|
|
__try
|
|
{
|
|
Assert (InsertPosition);
|
|
insert (InsertPosition, pMod);
|
|
Assert (S_OK == hr);
|
|
|
|
DbgVerifySorted();
|
|
}
|
|
__except(EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
delete pMod;
|
|
pMod = NULL;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Assert (dwFlags & INS_IGNORE_IF_DUP);
|
|
|
|
// Update the file size of the module if we didn't have it
|
|
// when it was first created.
|
|
//
|
|
if (0 == pMod->m_cbFileSize)
|
|
{
|
|
pMod->m_cbFileSize = cbFileSize;
|
|
}
|
|
}
|
|
|
|
*ppMod = pMod;
|
|
|
|
return hr;
|
|
}
|
|
|
|
CModule*
|
|
CModuleList::PBinarySearchModuleByName (
|
|
IN PCSTR pszFileName,
|
|
OUT CModuleList::iterator* pInsertPosition OPTIONAL)
|
|
{
|
|
// Find the module using a binary search.
|
|
//
|
|
if (size())
|
|
{
|
|
LONG Lo;
|
|
LONG Hi;
|
|
LONG Mid;
|
|
INT Result;
|
|
CModule* pScan;
|
|
|
|
Lo = 0;
|
|
Hi = size() - 1;
|
|
|
|
while (Hi >= Lo)
|
|
{
|
|
Mid = (Lo + Hi) / 2;
|
|
pScan = at(Mid);
|
|
|
|
Result = strcmp (pszFileName, pScan->m_pszFileName);
|
|
|
|
if (Result < 0)
|
|
{
|
|
Hi = Mid - 1;
|
|
}
|
|
else if (Result > 0)
|
|
{
|
|
Lo = Mid + 1;
|
|
}
|
|
else
|
|
{
|
|
return pScan;
|
|
}
|
|
}
|
|
|
|
// If we make it to here, the module was not found.
|
|
//
|
|
if (pInsertPosition)
|
|
{
|
|
*pInsertPosition = begin() + Lo;
|
|
Assert (*pInsertPosition >= begin());
|
|
Assert (*pInsertPosition <= end());
|
|
}
|
|
}
|
|
else if (pInsertPosition)
|
|
{
|
|
// Empty collection. Insert position is at the beginning.
|
|
//
|
|
*pInsertPosition = begin();
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
CModule*
|
|
CModuleList::PLinearFindModuleByName (
|
|
IN PCSTR pszFileName)
|
|
{
|
|
const_iterator iter;
|
|
CModule* pScan;
|
|
|
|
for (iter = begin(); iter != end(); iter++)
|
|
{
|
|
pScan = *iter;
|
|
Assert (pScan);
|
|
|
|
if (0 == strcmp(pszFileName, pScan->m_pszFileName))
|
|
{
|
|
return pScan;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
CModule*
|
|
CModuleList::RemoveLastModule ()
|
|
{
|
|
CModule* pMod = NULL;
|
|
if (size() > 0)
|
|
{
|
|
pMod = back();
|
|
AssertH(pMod);
|
|
pop_back();
|
|
}
|
|
return pMod;
|
|
}
|
|
|
|
#if DBG
|
|
VOID
|
|
CModuleList::DbgVerifySorted ()
|
|
{
|
|
const_iterator iter;
|
|
CModule* pScan;
|
|
CModule* pPrev = NULL;
|
|
|
|
if (size() > 1)
|
|
{
|
|
for (pPrev = *begin(), iter = begin() + 1; iter != end(); iter++)
|
|
{
|
|
pScan = *iter;
|
|
Assert (pScan);
|
|
|
|
Assert (strcmp(pPrev->m_pszFileName, pScan->m_pszFileName) < 0);
|
|
|
|
pPrev = pScan;
|
|
}
|
|
}
|
|
}
|
|
#endif
|