windows-nt/Source/XPSP1/NT/admin/wmi/wbem/winmgmt/wbemcomn/stackcom.cpp
2020-09-26 16:20:57 +08:00

233 lines
4.8 KiB
C++

/*++
Copyright (C) 1996-2001 Microsoft Corporation
Module Name:
STACKCOM.CPP
Abstract:
stack implementation.
History:
--*/
#include "precomp.h"
#include <stdio.h>
#ifdef _MT
#undef _MT
#include <yvals.h>
#define _MT
#endif
#include "arena.h"
#include "sync.h"
#include "flexarry.h"
#include <time.h>
#include <stdio.h>
#include <arrtempl.h>
#include <sync.h>
#include <malloc.h>
#include <imagehlp.h>
#include <execq.h>
#include "stackcom.h"
void* CStackRecord::mstatic_apReturns[1000];
void CStackRecord::Create(int nIgnore, BOOL bStatic)
{
m_dwNumItems = GetStackLen() - nIgnore;
if(bStatic)
{
m_apReturns = (void**)mstatic_apReturns;
m_bDelete = FALSE;
}
else
{
m_apReturns = new void*[m_dwNumItems];
m_bDelete = TRUE;
}
ReadStack(nIgnore, m_apReturns);
}
CStackRecord::~CStackRecord()
{
if(m_bDelete)
delete m_apReturns;
}
void CStackRecord::MakeCopy(CStackRecord& Other)
{
m_dwNumItems = Other.GetNumItems();
DWORD dwLen = Other.GetNumItems() * sizeof(void*);
m_apReturns = new void*[Other.GetNumItems()];
memcpy(m_apReturns, Other.GetItems(), dwLen);
m_bDelete = TRUE;
}
int CStackRecord::Compare(const CStackRecord& Other) const
{
int nDiff = GetNumItems()- Other.GetNumItems();
if(nDiff)
return nDiff;
return memcmp(GetItems(), Other.GetItems(), sizeof(void*) * GetNumItems());
}
DWORD CStackRecord::GetStackLen()
{
void* pFrame;
__asm
{
mov pFrame, ebp
}
CStackContinuation* pPrev = CStackContinuation::Get();
void* pEnd = NULL;
if(pPrev)
pEnd = pPrev->m_pThisStackEnd;
DWORD dwLen = 0;
while(!IsBadReadPtr(pFrame, sizeof(DWORD)))
{
dwLen++;
void** ppReturn = (void**)pFrame + 1;
void* pReturn = *ppReturn;
if(pReturn == pEnd)
break;
void* pNewFrame = *(void**)pFrame;
if(pNewFrame <= pFrame)
break;
pFrame = pNewFrame;
}
if(pPrev != NULL)
dwLen += pPrev->m_pPrevStack->GetNumItems();
return dwLen;
}
void CStackRecord::ReadStack(int nIgnore, void** apReturns)
{
void* pFrame;
__asm
{
mov pFrame, ebp
}
CStackContinuation* pPrev = CStackContinuation::Get();
void* pEnd = NULL;
if(pPrev)
pEnd = pPrev->m_pThisStackEnd;
while(!IsBadReadPtr(pFrame, sizeof(DWORD)))
{
void** ppReturn = (void**)pFrame + 1;
void* pReturn = *ppReturn;
if(pReturn == pEnd)
break;
if(nIgnore == 0)
*(apReturns++) = pReturn;
else
nIgnore--;
void* pNewFrame = *(void**)pFrame;
if(pNewFrame <= pFrame)
break;
pFrame = pNewFrame;
}
if(pPrev != NULL)
{
memcpy(apReturns, pPrev->m_pPrevStack->m_apReturns,
sizeof(void*) * pPrev->m_pPrevStack->GetNumItems());
}
}
void CStackRecord::Dump(FILE* f) const
{
fwrite(&m_dwNumItems, sizeof(DWORD), 1, f);
fwrite(m_apReturns, sizeof(void*), m_dwNumItems, f);
}
BOOL CStackRecord::Read(FILE* f, BOOL bStatic)
{
if(fread(&m_dwNumItems, sizeof(DWORD), 1, f) == 0)
return FALSE;
if(bStatic)
{
m_apReturns = (void**)mstatic_apReturns;
m_bDelete = FALSE;
}
else
{
m_apReturns = new void*[m_dwNumItems];
m_bDelete = TRUE;
}
return (fread(m_apReturns, sizeof(void*), m_dwNumItems, f) != 0);
}
void CAllocRecord::Dump(FILE* f) const
{
fwrite(&m_dwTotalAlloc, sizeof(DWORD), 1, f);
fwrite(&m_dwNumTimes, sizeof(DWORD), 1, f);
m_Stack.Dump(f);
DWORD dwNumBuffers = m_apBuffers.Size();
fwrite(&dwNumBuffers, sizeof(DWORD), 1, f);
fwrite(m_apBuffers.GetArrayPtr(), sizeof(void*), dwNumBuffers, f);
}
void CAllocRecord::Subtract(CAllocRecord& Other)
{
m_dwTotalAlloc -= Other.m_dwTotalAlloc;
m_dwNumTimes -= Other.m_dwNumTimes;
for(int i = 0; i < m_apBuffers.Size(); i++)
{
for(int j = 0; j < Other.m_apBuffers.Size(); j++)
if(Other.m_apBuffers[j] == m_apBuffers[i])
break;
if(j < Other.m_apBuffers.Size())
{
m_apBuffers.RemoveAt(i);
i--;
}
}
}
CTls CStackContinuation::mtls_CurrentCont;
CStackContinuation* CStackContinuation::Set(CStackContinuation* pNew)
{
CStackContinuation* pPrev = (CStackContinuation*)(void*)mtls_CurrentCont;
mtls_CurrentCont = pNew;
if(pNew)
{
void* p;
__asm
{
mov eax, [ebp]
mov eax, [eax+4]
mov p, eax
}
pNew->m_pThisStackEnd = p;
}
return pPrev;
}
CStackContinuation* CStackContinuation::Get()
{
CStackContinuation* pPrev = (CStackContinuation*)(void*)mtls_CurrentCont;
return pPrev;
}