|
|
#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
|