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.
 
 
 
 
 
 

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