Rebranded to PoolMonX. Added columns for driver name

This commit is contained in:
Pavel Yosifovich
2017-05-29 22:14:19 +03:00
parent f1d28a9007
commit 68951386da
12 changed files with 4787 additions and 281 deletions
+356 -260
View File
@@ -13,401 +13,497 @@ IMPLEMENT_DYNAMIC(CPoolListCtrl, CMFCListCtrl)
CPoolListCtrl::CPoolListCtrl()
{
m_pPoolInfo = (SYSTEM_POOLTAG_INFORMATION*)::malloc(m_PoolInfoSize);
m_pPoolInfo = (SYSTEM_POOLTAG_INFORMATION*)::malloc(m_PoolInfoSize);
}
CPoolListCtrl::~CPoolListCtrl()
{
::free(m_pPoolInfo);
::free(m_pPoolInfo);
}
BEGIN_MESSAGE_MAP(CPoolListCtrl, CMFCListCtrl)
ON_WM_CREATE()
ON_NOTIFY(HDN_ITEMCLICKA, 0, &CPoolListCtrl::OnHdnItemclick)
ON_NOTIFY(HDN_ITEMCLICKW, 0, &CPoolListCtrl::OnHdnItemclick)
ON_WM_TIMER()
ON_COMMAND(ID_VIEW_REFRESH, &CPoolListCtrl::OnViewRefresh)
ON_COMMAND_RANGE(ID_REFRESHINTERVAL_5SECONDS, ID_REFRESHINTERVAL_5SECONDS + 3, OnIntervalChange)
ON_UPDATE_COMMAND_UI_RANGE(ID_REFRESHINTERVAL_5SECONDS, ID_REFRESHINTERVAL_5SECONDS + 3, OnIntervalChangeUpdateUI)
ON_COMMAND(ID_VIEW_DYNAMICSORT, &CPoolListCtrl::OnViewDynamicsort)
ON_UPDATE_COMMAND_UI(ID_VIEW_DYNAMICSORT, &CPoolListCtrl::OnUpdateViewDynamicsort)
ON_WM_CREATE()
ON_NOTIFY(HDN_ITEMCLICKA, 0, &CPoolListCtrl::OnHdnItemclick)
ON_NOTIFY(HDN_ITEMCLICKW, 0, &CPoolListCtrl::OnHdnItemclick)
ON_WM_TIMER()
ON_COMMAND(ID_VIEW_REFRESH, &CPoolListCtrl::OnViewRefresh)
ON_COMMAND_RANGE(ID_REFRESHINTERVAL_5SECONDS, ID_REFRESHINTERVAL_5SECONDS + 3, OnIntervalChange)
ON_UPDATE_COMMAND_UI_RANGE(ID_REFRESHINTERVAL_5SECONDS, ID_REFRESHINTERVAL_5SECONDS + 3, OnIntervalChangeUpdateUI)
ON_COMMAND(ID_VIEW_DYNAMICSORT, &CPoolListCtrl::OnViewDynamicsort)
ON_UPDATE_COMMAND_UI(ID_VIEW_DYNAMICSORT, &CPoolListCtrl::OnUpdateViewDynamicsort)
END_MESSAGE_MAP()
int CPoolListCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CMFCListCtrl::OnCreate(lpCreateStruct) == -1)
return -1;
if (CMFCListCtrl::OnCreate(lpCreateStruct) == -1)
return -1;
m_Images.Create(16, 16, ILC_COLOR32, 4, 2);
m_Images.Add(AfxGetApp()->LoadIconW(IDI_PAGED));
m_Images.Add(AfxGetApp()->LoadIconW(IDI_NONPAGED));
m_Images.Create(16, 16, ILC_COLOR32, 4, 2);
m_Images.Add(AfxGetApp()->LoadIconW(IDI_PAGED));
m_Images.Add(AfxGetApp()->LoadIconW(IDI_NONPAGED));
SetImageList(&m_Images, LVSIL_SMALL);
SetImageList(&m_Images, LVSIL_SMALL);
//EnableMarkSortedColumn(FALSE);
//EnableMarkSortedColumn(FALSE);
CFont font;
font.CreatePointFont(100, L"Consolas");
CFont font;
font.CreatePointFont(100, L"Consolas");
LOGFONT lf;
GetFont()->GetLogFont(&lf);
LOGFONT lf;
GetFont()->GetLogFont(&lf);
SetFont(&font);
font.Detach();
SetFont(&font);
font.Detach();
font.DeleteObject();
font.CreateFontIndirectW(&lf);
GetHeaderCtrl().SetFont(&font);
font.Detach();
font.DeleteObject();
font.CreateFontIndirectW(&lf);
GetHeaderCtrl().SetFont(&font);
font.Detach();
InsertColumn(0, L"Tag", LVCFMT_CENTER, 80);
InsertColumn(1, L"Type", LVCFMT_CENTER, 80);
InsertColumn(2, L"Allocs", LVCFMT_RIGHT, 100);
InsertColumn(3, L"Frees", LVCFMT_RIGHT, 100);
InsertColumn(4, L"Diff", LVCFMT_RIGHT, 80);
InsertColumn(5, L"Bytes", LVCFMT_RIGHT, 100);
InsertColumn(6, L"KBytes", LVCFMT_RIGHT, 100);
InsertColumn(7, L"B / Alloc", LVCFMT_RIGHT, 80);
InsertColumn(ColumnType::TagName, L"Tag", LVCFMT_CENTER, 80);
InsertColumn(ColumnType::PoolType, L"Type", LVCFMT_CENTER, 80);
InsertColumn(ColumnType::Allocs, L"Allocs", LVCFMT_RIGHT, 100);
InsertColumn(ColumnType::Frees, L"Frees", LVCFMT_RIGHT, 100);
InsertColumn(ColumnType::Diff, L"Diff", LVCFMT_RIGHT, 80);
InsertColumn(ColumnType::Usage, L"Bytes", LVCFMT_RIGHT, 100);
InsertColumn(ColumnType::UsageKB, L"KBytes", LVCFMT_RIGHT, 100);
InsertColumn(ColumnType::PerAlloc, L"B / Alloc", LVCFMT_RIGHT, 80);
InsertColumn(ColumnType::SourceName, L"Source", LVCFMT_LEFT, 150);
InsertColumn(ColumnType::SourceDescription, L"Source Description", LVCFMT_LEFT, 350);
BuildPoolData();
LoadPoolTags();
SetTimer(1, m_Interval, nullptr);
BuildPoolData();
return 0;
SetTimer(1, m_Interval, nullptr);
return 0;
}
void CPoolListCtrl::LoadPoolTags() {
using namespace std;
auto hModule = AfxGetResourceHandle();
auto hResource = ::FindResource(hModule, MAKEINTRESOURCE(IDR_POOLTAG), L"TXT");
ASSERT(hResource);
auto hGlobal = ::LoadResource(hModule, hResource);
ASSERT(hGlobal);
auto data = static_cast<const char*>(::LockResource(hGlobal));
auto next = data;
for (; next; data = next + 1) {
next = strchr(data, '\n');
if (strncmp(data, "//", 2) == 0 || _strnicmp(data, "rem", 3) == 0
|| strncmp(data, "\r\n", 2) == 0)
continue;
// read the tag
string tag(data, data + 4);
// locate the first dash
auto dash1 = strchr(data, '-');
if (dash1 == nullptr)
continue;
// locate second dash
auto dash2 = strchr(dash1 + 1, '-');
if (dash2 == nullptr)
continue;
if (dash2 > next) {
dash2 = dash1;
dash1 = nullptr;
}
CStringA trimmedTag(tag.c_str());
//trimmedTag.Trim();
CStringW trimmedDriverName(L"");
if (dash1) {
string driverName(dash1 + 1, dash2);
trimmedDriverName = driverName.c_str();
trimmedDriverName.Trim();
}
string driverDesc(dash2 + 1, next - 1);
CStringW trimmedDriverDesc(driverDesc.c_str());
trimmedDriverDesc.Trim();
m_PoolTagMap.insert(make_pair(trimmedTag, make_pair(wstring(trimmedDriverName), wstring(trimmedDriverDesc))));
}
}
void CPoolListCtrl::BuildPoolData()
{
CWaitCursor wait;
CWaitCursor wait;
ULONG size;
auto status = ::NtQuerySystemInformation(SystemInformationClass::SystemPoolTagInformation, m_pPoolInfo, m_PoolInfoSize, &size);
if (status == 0) {
char tag[5] = { 0 };
int count = m_pPoolInfo->Count;
m_Tags.clear();
ULONG size;
auto status = ::NtQuerySystemInformation(SystemInformationClass::SystemPoolTagInformation, m_pPoolInfo, m_PoolInfoSize, &size);
if (status == 0) {
char tag[5] = { 0 };
int count = m_pPoolInfo->Count;
m_Tags.clear();
for (auto i = 0; i < count; i++) {
const auto& item = m_pPoolInfo->TagInfo[i];
::CopyMemory(tag, &item.Tag, 4);
for (auto i = 0; i < count; i++) {
const auto& item = m_pPoolInfo->TagInfo[i];
::CopyMemory(tag, &item.Tag, 4);
if (item.NonPagedAllocs > 0) {
AddItem(i, item, tag, true);
}
if (item.PagedAllocs > 0) {
AddItem(i, item, tag, false);
}
if (item.NonPagedAllocs > 0) {
AddItem(i, item, tag, true);
}
if (item.PagedAllocs > 0) {
AddItem(i, item, tag, false);
}
}
}
}
}
}
void CPoolListCtrl::UpdateItem(int n, const SYSTEM_POOLTAG& item, bool nonpaged)
void CPoolListCtrl::UpdateItem(int n, PoolTagInfo& info, bool nonpaged)
{
SetItemText(n, ColumnType::PoolType, nonpaged ? L"Non Paged" : L"Paged");
CString value;
value.Format(L"%u", nonpaged ? item.NonPagedAllocs : item.PagedAllocs);
SetItemText(n, ColumnType::Allocs, value);
const auto& item = info.Tag;
value.Format(L"%u", nonpaged ? item.NonPagedFrees : item.PagedFrees);
SetItemText(n, ColumnType::Frees, value);
SetItemText(n, ColumnType::PoolType, nonpaged ? L"Non Paged" : L"Paged");
CString value;
value.Format(L"%u", nonpaged ? item.NonPagedAllocs : item.PagedAllocs);
SetItemText(n, ColumnType::Allocs, value);
int diff;
value.Format(L"%u", nonpaged ? diff = item.NonPagedAllocs - item.NonPagedFrees : diff = item.PagedAllocs - item.PagedFrees);
SetItemText(n, ColumnType::Diff, value);
value.Format(L"%u", nonpaged ? item.NonPagedFrees : item.PagedFrees);
SetItemText(n, ColumnType::Frees, value);
auto used = nonpaged ? item.NonPagedUsed : item.PagedUsed;
value.Format(L"%u", used);
SetItemText(n, ColumnType::Usage, value);
int diff;
value.Format(L"%u", nonpaged ? diff = item.NonPagedAllocs - item.NonPagedFrees : diff = item.PagedAllocs - item.PagedFrees);
SetItemText(n, ColumnType::Diff, value);
value.Format(L"%u KB", (used + 512) >> 10);
SetItemText(n, ColumnType::UsageKB, value);
auto used = nonpaged ? item.NonPagedUsed : item.PagedUsed;
value.Format(L"%u", used);
SetItemText(n, ColumnType::Usage, value);
value.Format(L"%u", diff == 0 ? 0 : used / diff);
SetItemText(n, ColumnType::PerAlloc, value);
value.Format(L"%u KB", (used + 512) >> 10);
SetItemText(n, ColumnType::UsageKB, value);
value.Format(L"%u", diff == 0 ? 0 : used / diff);
SetItemText(n, ColumnType::PerAlloc, value);
auto driver = m_PoolTagMap.find(std::string((const char*)&item.Tag, (const char*)&item.Tag + 4));
if (driver != m_PoolTagMap.end()) {
SetItemText(n, ColumnType::SourceName, info.SourceName = driver->second.first.c_str());
SetItemText(n, ColumnType::SourceDescription, info.SourceDesc = driver->second.second.c_str());
}
}
void CPoolListCtrl::AddColor(int row, int col, COLORREF color)
{
m_CellColors.insert(std::make_pair(std::make_pair(row, col), color));
m_CellColors.insert(std::make_pair(std::make_pair(row, col), color));
}
bool CPoolListCtrl::ProcessChanges(int row, const SYSTEM_POOLTAG & newTag, const SYSTEM_POOLTAG & oldTag, bool nonpaged)
bool CPoolListCtrl::ProcessChanges(int row, const SYSTEM_POOLTAG& newTag, const SYSTEM_POOLTAG& oldTag, bool nonpaged)
{
if (::memcmp(&newTag, &oldTag, sizeof(newTag)) == 0)
return false;
if (::memcmp(&newTag, &oldTag, sizeof(newTag)) == 0)
return false;
const COLORREF PlusColor = Green, MinusColor = Red;
const COLORREF PlusColor = Green, MinusColor = Red;
if (nonpaged) {
if (newTag.NonPagedAllocs > oldTag.NonPagedAllocs)
AddColor(row, ColumnType::Allocs, PlusColor);
if (newTag.NonPagedFrees > oldTag.NonPagedFrees)
AddColor(row, ColumnType::Frees, PlusColor);
if (newTag.NonPagedUsed > oldTag.NonPagedUsed) {
AddColor(row, ColumnType::Usage, PlusColor);
AddColor(row, ColumnType::UsageKB, PlusColor);
}
else if (newTag.NonPagedUsed < oldTag.NonPagedUsed) {
AddColor(row, ColumnType::Usage, MinusColor);
AddColor(row, ColumnType::UsageKB, MinusColor);
}
if (newTag.NonPagedAllocs - newTag.NonPagedFrees > oldTag.NonPagedAllocs - oldTag.NonPagedFrees)
AddColor(row, ColumnType::Diff, PlusColor);
else if(newTag.NonPagedAllocs - newTag.NonPagedFrees < oldTag.NonPagedAllocs - oldTag.NonPagedFrees)
AddColor(row, ColumnType::Diff, MinusColor);
}
else {
if (newTag.PagedAllocs > oldTag.PagedAllocs)
AddColor(row, ColumnType::Allocs, PlusColor);
if (newTag.PagedFrees > oldTag.PagedFrees)
AddColor(row, ColumnType::Frees, PlusColor);
if (newTag.PagedUsed > oldTag.PagedUsed) {
AddColor(row, ColumnType::Usage, PlusColor);
AddColor(row, ColumnType::UsageKB, PlusColor);
}
else if (newTag.PagedUsed < oldTag.PagedUsed) {
AddColor(row, ColumnType::Usage, MinusColor);
AddColor(row, ColumnType::UsageKB, MinusColor);
}
if (newTag.PagedAllocs - newTag.PagedFrees > oldTag.PagedAllocs - oldTag.PagedFrees)
AddColor(row, ColumnType::Diff, PlusColor);
else if (newTag.PagedAllocs - newTag.PagedFrees < oldTag.PagedAllocs - oldTag.PagedFrees)
AddColor(row, ColumnType::Diff, MinusColor);
}
return true;
if (nonpaged) {
if (newTag.NonPagedAllocs > oldTag.NonPagedAllocs)
AddColor(row, ColumnType::Allocs, PlusColor);
if (newTag.NonPagedFrees > oldTag.NonPagedFrees)
AddColor(row, ColumnType::Frees, PlusColor);
if (newTag.NonPagedUsed > oldTag.NonPagedUsed) {
AddColor(row, ColumnType::Usage, PlusColor);
AddColor(row, ColumnType::UsageKB, PlusColor);
}
else if (newTag.NonPagedUsed < oldTag.NonPagedUsed) {
AddColor(row, ColumnType::Usage, MinusColor);
AddColor(row, ColumnType::UsageKB, MinusColor);
}
if (newTag.NonPagedAllocs - newTag.NonPagedFrees > oldTag.NonPagedAllocs - oldTag.NonPagedFrees)
AddColor(row, ColumnType::Diff, PlusColor);
else if (newTag.NonPagedAllocs - newTag.NonPagedFrees < oldTag.NonPagedAllocs - oldTag.NonPagedFrees)
AddColor(row, ColumnType::Diff, MinusColor);
}
else {
if (newTag.PagedAllocs > oldTag.PagedAllocs)
AddColor(row, ColumnType::Allocs, PlusColor);
if (newTag.PagedFrees > oldTag.PagedFrees)
AddColor(row, ColumnType::Frees, PlusColor);
if (newTag.PagedUsed > oldTag.PagedUsed) {
AddColor(row, ColumnType::Usage, PlusColor);
AddColor(row, ColumnType::UsageKB, PlusColor);
}
else if (newTag.PagedUsed < oldTag.PagedUsed) {
AddColor(row, ColumnType::Usage, MinusColor);
AddColor(row, ColumnType::UsageKB, MinusColor);
}
if (newTag.PagedAllocs - newTag.PagedFrees > oldTag.PagedAllocs - oldTag.PagedFrees)
AddColor(row, ColumnType::Diff, PlusColor);
else if (newTag.PagedAllocs - newTag.PagedFrees < oldTag.PagedAllocs - oldTag.PagedFrees)
AddColor(row, ColumnType::Diff, MinusColor);
}
return true;
}
int CPoolListCtrl::AddItem(int index, const SYSTEM_POOLTAG& item, PCSTR tag, bool nonpaged)
{
int n = InsertItem(index, CString(tag), nonpaged ? 1 : 0);
PoolTagInfo info = { item };
UpdateItem(n, item, nonpaged);
int n = InsertItem(index, CString(tag), nonpaged ? 1 : 0);
ULONG key = nonpaged ? (item.TagUlong | NonPagedBit) : item.TagUlong;
UpdateItem(n, info, nonpaged);
m_Tags.insert(std::make_pair(key, item));
ULONG key = nonpaged ? (item.TagUlong | NonPagedBit) : item.TagUlong;
SetItemData(n, key);
m_Tags.insert(std::make_pair(key, info));
return n;
SetItemData(n, key);
return n;
}
static int CompareStrings(PCWSTR s1, PCWSTR s2) {
if (s1 == s2)
return 0;
if (s1 == nullptr)
return -1;
if (s2 == nullptr)
return 1;
return ::wcscmp(s1, s2);
}
int CPoolListCtrl::OnCompareItems(LPARAM lParam1, LPARAM lParam2, int iColumn)
{
ASSERT(m_Tags.find(lParam1) != m_Tags.end());
ASSERT(m_Tags.find(lParam2) != m_Tags.end());
ASSERT(m_Tags.find(lParam1) != m_Tags.end());
ASSERT(m_Tags.find(lParam2) != m_Tags.end());
const auto& item1 = m_Tags[lParam1];
const auto& item2 = m_Tags[lParam2];
const auto& info1 = m_Tags[lParam1];
const auto& info2 = m_Tags[lParam2];
auto nonPaged1 = ((ULONG)lParam1) & NonPagedBit;
auto nonPaged2 = ((ULONG)lParam2) & NonPagedBit;
const auto& item1 = info1.Tag;
const auto& item2 = info2.Tag;
long long order;
auto nonPaged1 = ((ULONG)lParam1) & NonPagedBit;
auto nonPaged2 = ((ULONG)lParam2) & NonPagedBit;
switch (iColumn) {
case ColumnType::TagName:
order = (long long)ReverseTag(item1.TagUlong) - ReverseTag(item2.TagUlong);
break;
long long order;
case ColumnType::PoolType:
if (nonPaged1 == nonPaged2)
return 0;
switch (iColumn) {
case ColumnType::TagName:
order = (long long)ReverseTag(item1.TagUlong) - ReverseTag(item2.TagUlong);
break;
order = nonPaged1 ? -1 : 1;
break;
case ColumnType::PoolType:
if (nonPaged1 == nonPaged2)
return 0;
case ColumnType::Allocs:
order = (long long)(nonPaged1 ? item1.NonPagedAllocs : item1.PagedAllocs) - (nonPaged2 ? item2.NonPagedAllocs : item2.PagedAllocs);
break;
order = nonPaged1 ? -1 : 1;
break;
case ColumnType::Frees:
order = (long long)(nonPaged1 ? item1.NonPagedFrees : item1.PagedFrees) - (nonPaged2 ? item2.NonPagedFrees : item2.PagedFrees);
break;
case ColumnType::Allocs:
order = (long long)(nonPaged1 ? item1.NonPagedAllocs : item1.PagedAllocs) - (nonPaged2 ? item2.NonPagedAllocs : item2.PagedAllocs);
break;
case ColumnType::Diff:
{
auto diff1 = (nonPaged1 ? item1.NonPagedAllocs : item1.PagedAllocs) - (nonPaged1 ? item1.NonPagedFrees : item1.PagedFrees);
auto diff2 = (nonPaged2 ? item2.NonPagedAllocs : item2.PagedAllocs) - (nonPaged2 ? item2.NonPagedFrees : item2.PagedFrees);
order = (long long)(diff1) - diff2;
break;
}
case ColumnType::Frees:
order = (long long)(nonPaged1 ? item1.NonPagedFrees : item1.PagedFrees) - (nonPaged2 ? item2.NonPagedFrees : item2.PagedFrees);
break;
case ColumnType::Usage:
case ColumnType::UsageKB:
order = (long long)(nonPaged1 ? item1.NonPagedUsed : item1.PagedUsed) - (nonPaged2 ? item2.NonPagedUsed : item2.PagedUsed);
break;
case ColumnType::Diff:
{
auto diff1 = (nonPaged1 ? item1.NonPagedAllocs : item1.PagedAllocs) - (nonPaged1 ? item1.NonPagedFrees : item1.PagedFrees);
auto diff2 = (nonPaged2 ? item2.NonPagedAllocs : item2.PagedAllocs) - (nonPaged2 ? item2.NonPagedFrees : item2.PagedFrees);
order = (long long)(diff1)-diff2;
break;
}
case ColumnType::PerAlloc:
auto allocs1 = (nonPaged1 ? item1.NonPagedAllocs : item1.PagedAllocs);
auto allocs2 = (nonPaged2 ? item2.NonPagedAllocs : item2.PagedAllocs);
auto frees1 = (nonPaged1 ? item1.NonPagedFrees : item1.PagedFrees);
auto frees2 = (nonPaged2 ? item2.NonPagedFrees : item2.PagedFrees);
auto used1 = (nonPaged1 ? item1.NonPagedUsed : item1.PagedUsed);
auto used2 = (nonPaged2 ? item2.NonPagedUsed : item2.PagedUsed);
case ColumnType::Usage:
case ColumnType::UsageKB:
order = (long long)(nonPaged1 ? item1.NonPagedUsed : item1.PagedUsed) - (nonPaged2 ? item2.NonPagedUsed : item2.PagedUsed);
break;
auto diff1 = allocs1 - frees1, diff2 = allocs2 - frees2;
case ColumnType::PerAlloc: {
auto allocs1 = (nonPaged1 ? item1.NonPagedAllocs : item1.PagedAllocs);
auto allocs2 = (nonPaged2 ? item2.NonPagedAllocs : item2.PagedAllocs);
auto frees1 = (nonPaged1 ? item1.NonPagedFrees : item1.PagedFrees);
auto frees2 = (nonPaged2 ? item2.NonPagedFrees : item2.PagedFrees);
auto used1 = (nonPaged1 ? item1.NonPagedUsed : item1.PagedUsed);
auto used2 = (nonPaged2 ? item2.NonPagedUsed : item2.PagedUsed);
order = (long long)(diff1 ? used1 / diff1 : 0) - (diff2 ? used2 / diff2 : 0);
break;
}
auto diff1 = allocs1 - frees1, diff2 = allocs2 - frees2;
if (order == 0)
return 0;
order = (long long)(diff1 ? used1 / diff1 : 0) - (diff2 ? used2 / diff2 : 0);
break;
}
return order > 0 ? 1 : -1;
case ColumnType::SourceName:
return CompareStrings(info1.SourceName, info2.SourceName);
case ColumnType::SourceDescription:
return CompareStrings(info1.SourceDesc, info2.SourceDesc);
}
if (order == 0)
return 0;
return order > 0 ? 1 : -1;
}
ULONG CPoolListCtrl::ReverseTag(ULONG tagUlong)
{
BYTE* tag = (BYTE*)&tagUlong;
std::swap(tag[0], tag[3]);
std::swap(tag[1], tag[2]);
return tagUlong;
BYTE* tag = (BYTE*)&tagUlong;
std::swap(tag[0], tag[3]);
std::swap(tag[1], tag[2]);
return tagUlong;
}
void CPoolListCtrl::OnHdnItemclick(NMHDR *pNMHDR, LRESULT *pResult)
{
auto phdr = reinterpret_cast<LPNMHEADER>(pNMHDR);
auto phdr = reinterpret_cast<LPNMHEADER>(pNMHDR);
if (m_SortColumn != phdr->iItem) {
m_SortColumn = phdr->iItem;
m_Ascending = true;
}
else {
m_Ascending = !m_Ascending;
}
if (m_SortColumn != phdr->iItem) {
m_SortColumn = phdr->iItem;
m_Ascending = true;
}
else {
m_Ascending = !m_Ascending;
}
Sort(m_SortColumn, m_Ascending ? TRUE : FALSE);
Sort(m_SortColumn, m_Ascending ? TRUE : FALSE);
*pResult = 0;
*pResult = 0;
}
void CPoolListCtrl::RefreshPoolData()
{
CWaitCursor wait;
CWaitCursor wait;
ULONG size;
auto status = ::NtQuerySystemInformation(SystemInformationClass::SystemPoolTagInformation, m_pPoolInfo, m_PoolInfoSize, &size);
if (status == 0) {
char tag[5] = { 0 };
int count = m_pPoolInfo->Count;
LVFINDINFO lvfi = { LVFI_PARAM };
ULONG size;
auto status = ::NtQuerySystemInformation(SystemInformationClass::SystemPoolTagInformation, m_pPoolInfo, m_PoolInfoSize, &size);
if (status == 0) {
char tag[5] = { 0 };
int count = m_pPoolInfo->Count;
LVFINDINFO lvfi = { LVFI_PARAM };
int row;
CRect rc;
m_Update = true;
for (const auto& cell : m_CellColors) {
row = cell.first.first;
RedrawItems(row, row);
}
m_Update = false;
int row;
CRect rc;
m_Update = true;
for (const auto& cell : m_CellColors) {
row = cell.first.first;
RedrawItems(row, row);
}
m_Update = false;
LockWindowUpdate();
LockWindowUpdate();
m_CellColors.clear();
m_CellColors.clear();
for (auto i = 0; i < count; i++) {
const auto& item = m_pPoolInfo->TagInfo[i];
::CopyMemory(tag, &item.Tag, 4);
for (auto i = 0; i < count; i++) {
PoolTagInfo info{ };
info.Tag = m_pPoolInfo->TagInfo[i];
const auto& item = info.Tag;
if (item.NonPagedAllocs > 0) {
// find the tag (if exists)
auto it = m_Tags.find(item.TagUlong | NonPagedBit);
if (it == m_Tags.end())
AddItem(GetItemCount(), item, tag, true);
else {
// find existing item
lvfi.lParam = item.TagUlong | NonPagedBit;
int n = FindItem(&lvfi);
ASSERT(n >= 0);
if (ProcessChanges(n, item, it->second, true)) {
UpdateItem(n, item, true);
m_Tags[lvfi.lParam] = item;
}
}
}
if (item.PagedAllocs > 0) {
auto it = m_Tags.find(item.TagUlong);
if (it == m_Tags.end())
AddItem(GetItemCount(), item, tag, false);
else {
// find existing item
lvfi.lParam = item.TagUlong;
int n = FindItem(&lvfi);
ASSERT(n >= 0);
if (ProcessChanges(n, item, it->second, false)) {
UpdateItem(n, item, false);
m_Tags[item.TagUlong] = item;
}
}
}
}
if (m_DynamicSort && m_SortColumn >= 0)
Sort(m_SortColumn, m_Ascending);
::CopyMemory(tag, &item.Tag, 4);
UnlockWindowUpdate();
if (item.NonPagedAllocs > 0) {
// find the tag (if exists)
auto it = m_Tags.find(item.TagUlong | NonPagedBit);
if (it == m_Tags.end())
AddItem(GetItemCount(), item, tag, true);
else {
// find existing item
lvfi.lParam = item.TagUlong | NonPagedBit;
int n = FindItem(&lvfi);
ASSERT(n >= 0);
if (ProcessChanges(n, item, it->second.Tag, true)) {
UpdateItem(n, info, true);
m_Tags[lvfi.lParam] = info;
}
}
}
if (item.PagedAllocs > 0) {
auto it = m_Tags.find(item.TagUlong);
if (it == m_Tags.end())
AddItem(GetItemCount(), item, tag, false);
else {
// find existing item
lvfi.lParam = item.TagUlong;
int n = FindItem(&lvfi);
ASSERT(n >= 0);
if (ProcessChanges(n, item, it->second.Tag, false)) {
UpdateItem(n, info, false);
m_Tags[item.TagUlong] = info;
}
}
}
}
if (m_DynamicSort && m_SortColumn >= 0)
Sort(m_SortColumn, m_Ascending);
}
UnlockWindowUpdate();
}
}
void CPoolListCtrl::Pause(bool pause)
{
if (pause)
KillTimer(1);
else
SetTimer(1, m_Interval, nullptr);
m_Paused = pause;
if (pause)
KillTimer(1);
else
SetTimer(1, m_Interval, nullptr);
m_Paused = pause;
}
void CPoolListCtrl::OnTimer(UINT_PTR nIDEvent)
{
if (nIDEvent == 1) {
RefreshPoolData();
TRACE(L"refresh: %d\n", ::GetTickCount());
}
if (nIDEvent == 1) {
RefreshPoolData();
TRACE(L"refresh: %d\n", ::GetTickCount());
}
}
void CPoolListCtrl::OnViewRefresh()
{
RefreshPoolData();
RefreshPoolData();
}
COLORREF CPoolListCtrl::OnGetCellBkColor(int row, int col)
{
if (m_Update)
return GetBkColor();
if (m_Update)
return GetBkColor();
auto it = m_CellColors.find(std::make_pair(row, col));
return it == m_CellColors.end() ? GetBkColor() : it->second;
auto it = m_CellColors.find(std::make_pair(row, col));
return it == m_CellColors.end() ? GetBkColor() : it->second;
}
void CPoolListCtrl::OnIntervalChange(UINT id)
{
m_IntervalIndex = id - ID_REFRESHINTERVAL_5SECONDS;
m_IntervalIndex = id - ID_REFRESHINTERVAL_5SECONDS;
const int intervals[] = { 5000, 10000, 30 * 1000, 60 * 1000 };
const int intervals[] = { 5000, 10000, 30 * 1000, 60 * 1000 };
if (!m_Paused)
SetTimer(1, intervals[m_IntervalIndex], nullptr);
if (!m_Paused)
SetTimer(1, intervals[m_IntervalIndex], nullptr);
}
void CPoolListCtrl::OnIntervalChangeUpdateUI(CCmdUI* pCmdUI)
{
pCmdUI->SetRadio(pCmdUI->m_nID - ID_REFRESHINTERVAL_5SECONDS == m_IntervalIndex);
pCmdUI->SetRadio(pCmdUI->m_nID - ID_REFRESHINTERVAL_5SECONDS == m_IntervalIndex);
}
void CPoolListCtrl::OnViewDynamicsort()
{
m_DynamicSort = !m_DynamicSort;
m_DynamicSort = !m_DynamicSort;
}
void CPoolListCtrl::OnUpdateViewDynamicsort(CCmdUI *pCmdUI)
{
pCmdUI->SetCheck(m_DynamicSort);
pCmdUI->SetCheck(m_DynamicSort);
}
+16 -3
View File
@@ -18,15 +18,21 @@ public:
static const unsigned NonPagedBit = 0x80000000;
private:
struct PoolTagInfo {
SYSTEM_POOLTAG Tag;
PCWSTR SourceName;
PCWSTR SourceDesc;
};
CImageList m_Images;
std::map<ULONG, SYSTEM_POOLTAG> m_Tags;
std::map<ULONG, PoolTagInfo> m_Tags;
std::map<std::pair<int, int>, COLORREF> m_CellColors;
int m_SortColumn = -1;
bool m_Ascending = true;
int AddItem(int index, const SYSTEM_POOLTAG&, PCSTR tag, bool nonpaged);
void UpdateItem(int index, const SYSTEM_POOLTAG& tag, bool nonpaged);
void UpdateItem(int index, PoolTagInfo& tag, bool nonpaged);
bool ProcessChanges(int row, const SYSTEM_POOLTAG& newTag, const SYSTEM_POOLTAG& oldTag, bool nonpaged);
void AddColor(int row, int col, COLORREF color);
@@ -51,7 +57,9 @@ private:
Diff,
Usage,
UsageKB,
PerAlloc
PerAlloc,
SourceName,
SourceDescription
};
bool m_Update = false;
@@ -60,6 +68,11 @@ private:
bool m_DynamicSort = true;
int m_IntervalIndex = 1;
std::map<std::string, std::pair<std::wstring, std::wstring>> m_PoolTagMap;
private:
void LoadPoolTags();
protected:
DECLARE_MESSAGE_MAP()
public:
+10 -2
View File
@@ -148,7 +148,7 @@ FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
ICON IDR_MAINFRAME,IDC_STATIC,14,14,20,20
LTEXT "Kernel Pool Monitor, Version 1.0",IDC_STATIC,42,14,175,8,SS_NOPREFIX
LTEXT "Copyright (C) 2016 by Pavel Yosifovich",IDC_STATIC,42,26,177,8
LTEXT "Copyright (C) 2016-2017 by Pavel Yosifovich",IDC_STATIC,42,26,177,8
DEFPUSHBUTTON "OK",IDOK,103,59,50,14,WS_GROUP
END
@@ -242,6 +242,14 @@ BEGIN
END
/////////////////////////////////////////////////////////////////////////////
//
// TXT
//
IDR_POOLTAG TXT "res\\pooltag.txt"
/////////////////////////////////////////////////////////////////////////////
//
// String Table
@@ -254,7 +262,7 @@ END
STRINGTABLE
BEGIN
IDR_MAINFRAME "Kernel Pool Monitor"
IDR_MAINFRAME "Kernel Pool Monitor (C)2016-2017 by Pavel Yosifovich"
END
STRINGTABLE
+3 -3
View File
@@ -1,9 +1,9 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
# Visual Studio 15
VisualStudioVersion = 15.0.26430.6
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PoolMonEx", "PoolMonEx.vcxproj", "{26A93265-52DE-4226-9974-AC437B0EC988}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PoolMonX", "PoolMonX.vcxproj", "{26A93265-52DE-4226-9974-AC437B0EC988}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
+7 -5
View File
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -23,19 +23,20 @@
<RootNamespace>PoolMonEx</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
<Keyword>MFCProj</Keyword>
<ProjectName>PoolMonX</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<UseOfMfc>Dynamic</UseOfMfc>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<UseOfMfc>Static</UseOfMfc>
@@ -43,14 +44,14 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<UseOfMfc>Dynamic</UseOfMfc>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<UseOfMfc>Dynamic</UseOfMfc>
@@ -184,6 +185,7 @@
</ItemDefinitionGroup>
<ItemGroup>
<Text Include="ReadMe.txt" />
<Text Include="res\pooltag.txt" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="MainFrm.h" />
@@ -16,6 +16,7 @@
</ItemGroup>
<ItemGroup>
<Text Include="ReadMe.txt" />
<Text Include="res\pooltag.txt" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="PoolMonEx.h">
+2 -4
View File
@@ -3,6 +3,7 @@
//
#include "stdafx.h"
#include "resource.h"
#include "PoolMonEx.h"
#include "PoolView.h"
@@ -10,7 +11,6 @@
#define new DEBUG_NEW
#endif
// CPoolView
CPoolView::CPoolView() {
@@ -30,8 +30,6 @@ BEGIN_MESSAGE_MAP(CPoolView, CWnd)
ON_UPDATE_COMMAND_UI(ID_VIEW_PAUSE, &CPoolView::OnUpdateViewPause)
END_MESSAGE_MAP()
// CPoolView message handlers
BOOL CPoolView::PreCreateWindow(CREATESTRUCT& cs) {
@@ -58,7 +56,7 @@ int CPoolView::OnCreate(LPCREATESTRUCT lpCreateStruct) {
m_List.Create(WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SINGLESEL | WS_CLIPSIBLINGS, CRect(), this, 123);
m_List.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_AUTOSIZECOLUMNS | LVS_EX_DOUBLEBUFFER);
return 0;
return 0;
}
+2 -2
View File
@@ -34,6 +34,8 @@ public:
public:
virtual ~CPoolView();
virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo);
// Generated message map functions
protected:
CPoolListCtrl m_List;
@@ -41,12 +43,10 @@ protected:
afx_msg void OnPaint();
DECLARE_MESSAGE_MAP()
public:
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnEditCopy();
virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo);
afx_msg void OnViewPause();
afx_msg void OnUpdateViewPause(CCmdUI *pCmdUI);
};
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

+4386
View File
File diff suppressed because it is too large Load Diff
+3 -2
View File
@@ -9,6 +9,7 @@
#define IDR_PoolMonExTYPE 130
#define IDI_NONPAGED 310
#define IDI_PAGED 311
#define IDR_POOLTAG 314
#define IDC_REFRESH 1000
#define ID_FILE_SAVE32771 32771
#define ID_VIEW_REFRESH 32772
@@ -24,8 +25,8 @@
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 314
#define _APS_NEXT_COMMAND_VALUE 32784
#define _APS_NEXT_RESOURCE_VALUE 315
#define _APS_NEXT_COMMAND_VALUE 32786
#define _APS_NEXT_CONTROL_VALUE 1003
#define _APS_NEXT_SYMED_VALUE 310
#endif
+1
View File
@@ -34,6 +34,7 @@
#endif // _AFX_NO_AFXCMN_SUPPORT
#include <afxcontrolbars.h> // MFC support for ribbons and control bars
#include <string>
#ifdef _UNICODE