1
0
Fork 0

handles and windows view (#1417)

* handles and windows view

* use references view for heap, cleaned up

* fix #1424 use decimal pid and tid

* thread name in windows view

* fix something when not debugging

* heaps view hidden
This commit is contained in:
Torusrxxx 2017-02-18 12:56:59 +00:00 committed by Duncan Ogilvie
parent 146f6eee99
commit 1ae3b7d178
8 changed files with 361 additions and 7 deletions

View File

@ -26,6 +26,7 @@
#include "tcpconnections.h"
#include "watch.h"
#include "animate.h"
#include "thread.h"
static DBGFUNCTIONS _dbgfunctions;
@ -295,6 +296,22 @@ static bool _enumtcpconnections(ListOf(TCPCONNECTIONINFO) connections)
return BridgeList<TCPCONNECTIONINFO>::CopyData(connections, connectionsV);
}
static bool _enumwindows(ListOf(WINDOW_INFO) windows)
{
std::vector<WINDOW_INFO> windowInfoV;
if(!HandlesEnumWindows(windowInfoV))
return false;
return BridgeList<WINDOW_INFO>::CopyData(windows, windowInfoV);
}
static bool _enumheaps(ListOf(HEAPINFO) heaps)
{
std::vector<HEAPINFO> heapInfoV;
if(!HandlesEnumHeaps(heapInfoV))
return false;
return BridgeList<HEAPINFO>::CopyData(heaps, heapInfoV);
}
void dbgfunctionsinit()
{
_dbgfunctions.AssembleAtEx = _assembleatex;
@ -352,4 +369,7 @@ void dbgfunctionsinit()
_dbgfunctions.AnimateCommand = _dbg_animatecommand;
_dbgfunctions.DbgSetDebuggeeInitScript = dbgsetdebuggeeinitscript;
_dbgfunctions.DbgGetDebuggeeInitScript = dbggetdebuggeeinitscript;
_dbgfunctions.EnumWindows = _enumwindows;
_dbgfunctions.EnumHeaps = _enumheaps;
_dbgfunctions.ThreadGetName = ThreadGetName;
}

View File

@ -94,6 +94,27 @@ typedef struct
unsigned int State;
} TCPCONNECTIONINFO;
typedef struct
{
duint handle;
duint parent;
DWORD threadId;
DWORD style;
DWORD styleEx;
duint wndProc;//not used yet
bool enabled;
RECT position;
char windowTitle[MAX_COMMENT_SIZE];
char windowClass[MAX_COMMENT_SIZE];
} WINDOW_INFO;
typedef struct
{
duint addr;
duint size;
duint flags;
} HEAPINFO;
typedef bool (*ASSEMBLEATEX)(duint addr, const char* instruction, char* error, bool fillnop);
typedef bool (*SECTIONFROMADDR)(duint addr, char* section);
typedef bool (*MODNAMEFROMADDR)(duint addr, char* modname, bool extension);
@ -149,7 +170,12 @@ typedef bool(*MEMISCODEPAGE)(duint addr, bool refresh);
typedef bool(*ANIMATECOMMAND)(const char* command);
typedef void(*DBGSETDEBUGGEEINITSCRIPT)(const char* fileName);
typedef const char* (*DBGGETDEBUGGEEINITSCRIPT)();
typedef bool(*HANDLESENUMWINDOWS)(ListOf(WINDOW_INFO) windows);
typedef bool(*HANDLESENUMHEAPS)(ListOf(HEAPINFO) heaps);
typedef bool(*THREADGETNAME)(DWORD tid, char* name);
//The list of all the DbgFunctions() return value.
//WARNING: This list is append only. Do not insert things in the middle or plugins would break.
typedef struct DBGFUNCTIONS_
{
ASSEMBLEATEX AssembleAtEx;
@ -207,6 +233,9 @@ typedef struct DBGFUNCTIONS_
ANIMATECOMMAND AnimateCommand;
DBGSETDEBUGGEEINITSCRIPT DbgSetDebuggeeInitScript;
DBGGETDEBUGGEEINITSCRIPT DbgGetDebuggeeInitScript;
HANDLESENUMWINDOWS EnumWindows;
HANDLESENUMHEAPS EnumHeaps;
THREADGETNAME ThreadGetName;
} DBGFUNCTIONS;
#ifdef BUILD_DBG

View File

@ -554,7 +554,19 @@ void DebugUpdateGui(duint disasm_addr, bool stack)
char threadName[MAX_THREAD_NAME_SIZE + 1] = "";
if(ThreadGetName(currentThreadId, threadName) && *threadName)
strcat_s(threadName, " ");
sprintf_s(title, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "File: %s - PID: %X - %sThread: %s%X%s")), szBaseFileName, fdProcessInfo->dwProcessId, modtext, threadName, currentThreadId, threadswitch);
//sprintf_s(title, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "File: %s - PID: %X - %sThread: %s%X%s")), szBaseFileName, fdProcessInfo->dwProcessId, modtext, threadName, currentThreadId, threadswitch);
char PIDnumber[64], TIDnumber[64];
if(settingboolget("Gui", "PidInHex"))
{
sprintf_s(PIDnumber, "%X", fdProcessInfo->dwProcessId);
sprintf_s(TIDnumber, "%X", currentThreadId);
}
else
{
sprintf_s(PIDnumber, "%u", fdProcessInfo->dwProcessId);
sprintf_s(TIDnumber, "%u", currentThreadId);
}
sprintf_s(title, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "File: %s - PID: %s - %sThread: %s%s%s")), szBaseFileName, PIDnumber, modtext, threadName, TIDnumber, threadswitch);
GuiUpdateWindowTitle(title);
GuiUpdateRegisterView();
GuiUpdateDisassemblyView();

View File

@ -1,6 +1,7 @@
#include "handles.h"
#include "undocumented.h"
#include "exception.h"
#include "debugger.h"
typedef struct _OBJECT_NAME_INFORMATION
{
@ -163,3 +164,133 @@ bool HandlesGetName(HANDLE hProcess, HANDLE remoteHandle, String & name, String
name = String(ErrorCodeToName(GetLastError()));
return true;
}
/**
\brief Get information about a window
*/
static WINDOW_INFO getWindowInfo(HWND hWnd)
{
WINDOW_INFO info;
memset(&info, 0, sizeof(info));
if(IsWindow(hWnd) != TRUE) //Not a window
{
return info;
}
info.handle = (duint)hWnd; //Get Window Handle
GetWindowRect(hWnd, &info.position); //Get Window Rect
info.style = GetWindowLong(hWnd, GWL_STYLE); //Get Window Style
info.styleEx = GetWindowLong(hWnd, GWL_EXSTYLE); //Get Window Stye ex
info.enabled = IsWindowEnabled(hWnd) == TRUE;
info.parent = (duint)GetParent(hWnd); //Get Parent Window
info.threadId = GetWindowThreadProcessId(hWnd, nullptr); //Get Window Thread Id
wchar_t limitedbuffer[256];
limitedbuffer[255] = 0;
GetWindowTextW(hWnd, limitedbuffer, 256);
if(limitedbuffer[255] != 0) //Window title too long. Add "..." to the end of buffer.
{
if(limitedbuffer[252] < 0xDC00 || limitedbuffer[252] > 0xDFFF) //protect the last surrogate of UTF-16 surrogate pair
limitedbuffer[252] = L'.';
limitedbuffer[253] = L'.';
limitedbuffer[254] = L'.';
limitedbuffer[255] = 0;
}
auto UTF8WindowTitle = StringUtils::Utf16ToUtf8(limitedbuffer);
memcpy(info.windowTitle, UTF8WindowTitle.c_str(), min(UTF8WindowTitle.size(), sizeof(info.windowTitle))); //Copy window title with repect to buffer size constraints
GetClassNameW(hWnd, limitedbuffer, 256);
if(limitedbuffer[255] != 0) //Window class too long. Add "..." to the end of buffer.
{
if(limitedbuffer[252] < 0xDC00 || limitedbuffer[252] > 0xDFFF) //protect the last surrogate of UTF-16 surrogate pair
limitedbuffer[252] = L'.';
limitedbuffer[253] = L'.';
limitedbuffer[254] = L'.';
limitedbuffer[255] = 0;
}
UTF8WindowTitle = StringUtils::Utf16ToUtf8(limitedbuffer);
memcpy(info.windowClass, UTF8WindowTitle.c_str(), min(UTF8WindowTitle.size(), sizeof(info.windowClass))); //Copy window class with repect to buffer size constraints
return info;
}
static BOOL CALLBACK getWindowInfoCallback(HWND hWnd, LPARAM lParam)
{
std::vector<WINDOW_INFO>* windowInfo = reinterpret_cast<std::vector<WINDOW_INFO>*>(lParam);
DWORD pid = 0;
GetWindowThreadProcessId(hWnd, &pid);
if(pid == fdProcessInfo->dwProcessId)
{
windowInfo->push_back(getWindowInfo(hWnd));
}
return TRUE;
}
/**
\brief Enumerates the window and return a list of all the windows owned by the debuggee (currently only top level windows)
*/
bool HandlesEnumWindows(std::vector<WINDOW_INFO> & windowsList)
{
std::vector<WINDOW_INFO> childWindowsList;
EnumWindows(getWindowInfoCallback, (LPARAM)&windowsList);
auto i = windowsList.begin();
for(auto & i = windowsList.cbegin(); i != windowsList.cend(); i++)
{
EnumChildWindows((HWND)i->handle, getWindowInfoCallback, (LPARAM)&childWindowsList);
}
for(auto & i = childWindowsList.cbegin(); i != childWindowsList.cend(); i++)
{
windowsList.push_back(*i);
}
return true;
}
/**
\brief Enumerates the heap and return a list of all the heaps in the debuggee
*/
bool HandlesEnumHeaps(std::vector<HEAPINFO> & heapList)
{
// Slow and official method to enum all heap blocks.
/*
HEAPLIST32 hl;
Handle hHeapSnap = CreateToolhelp32Snapshot(TH32CS_SNAPHEAPLIST, fdProcessInfo->dwProcessId);
hl.dwSize = sizeof(HEAPLIST32);
if(hHeapSnap == INVALID_HANDLE_VALUE)
{
return false;
}
if(Heap32ListFirst(hHeapSnap, &hl))
{
do
{
HEAPENTRY32 he;
ZeroMemory(&he, sizeof(HEAPENTRY32));
he.dwSize = sizeof(HEAPENTRY32);
if(Heap32First(&he, fdProcessInfo->dwProcessId, hl.th32HeapID))
{
do
{
HEAPINFO heapInfo;
memset(&heapInfo, 0, sizeof(heapInfo));
heapInfo.addr = he.dwAddress;
heapInfo.size = he.dwBlockSize;
heapInfo.flags = he.dwFlags;
heapList.push_back(heapInfo);
he.dwSize = sizeof(HEAPENTRY32);
}
while(Heap32Next(&he));
}
hl.dwSize = sizeof(HEAPLIST32);
}
while(Heap32ListNext(hHeapSnap, &hl));
}
else
{
return false;
}
return true;
*/
return false;
}

View File

@ -1,7 +1,12 @@
#pragma once
#ifndef HANDLES_H
#define HANDLES_H
#include "_global.h"
#include "_dbgfunctions.h"
bool HandlesEnum(duint pid, std::vector<HANDLEINFO> & handlesList);
bool HandlesGetName(HANDLE hProcess, HANDLE remoteHandle, String & name, String & typeName);
bool HandlesGetName(HANDLE hProcess, HANDLE remoteHandle, String & name, String & typeName);
bool HandlesEnumWindows(std::vector<WINDOW_INFO> & windowsList);
bool HandlesEnumHeaps(std::vector<HEAPINFO> & heapList);
#endif //HANDLES_H

View File

@ -104,7 +104,8 @@ void CallStackView::contextMenuSlot(const QPoint pos)
{
QMenu wMenu(this); //create context menu
mMenuBuilder->build(&wMenu);
wMenu.exec(mapToGlobal(pos)); //execute context menu
if(!wMenu.isEmpty())
wMenu.exec(mapToGlobal(pos)); //execute context menu
}
void CallStackView::followAddress()

View File

@ -3,6 +3,9 @@
#include "VersionHelpers.h"
#include "StdTable.h"
#include "LabeledSplitter.h"
#include "StringUtil.h"
#include "ReferenceView.h"
#include "MainWindow.h"
#include <QVBoxLayout>
HandlesView::HandlesView(QWidget* parent) : QWidget(parent)
@ -19,6 +22,20 @@ HandlesView::HandlesView(QWidget* parent) : QWidget(parent)
mHandlesTable->addColumnAt(8 + wCharWidth * 20, tr("Name"), false);
mHandlesTable->loadColumnFromConfig("Handle");
mWindowsTable = new StdTable(this);
mWindowsTable->setWindowTitle("Windows");
mWindowsTable->setDrawDebugOnly(true);
mWindowsTable->setContextMenuPolicy(Qt::CustomContextMenu);
mWindowsTable->addColumnAt(8 + 8 * wCharWidth, tr("Handle"), false);
mWindowsTable->addColumnAt(8 + 120 * wCharWidth, tr("Title"), false);
mWindowsTable->addColumnAt(8 + 40 * wCharWidth, tr("Class"), false);
mWindowsTable->addColumnAt(8 + 8 * wCharWidth, tr("Thread"), false);
mWindowsTable->addColumnAt(8 + 16 * wCharWidth, tr("Style"), false);
mWindowsTable->addColumnAt(8 + 16 * wCharWidth, tr("StyleEx"), false);
mWindowsTable->addColumnAt(8 + 8 * wCharWidth, tr("Parent"), false);
mWindowsTable->addColumnAt(8 + 20 * wCharWidth, tr("Size"), false);
mWindowsTable->addColumnAt(16, tr("Enable"), false);
mTcpConnectionsTable = new StdTable(this);
mTcpConnectionsTable->setWindowTitle("TcpConnections");
mTcpConnectionsTable->setDrawDebugOnly(true);
@ -27,7 +44,15 @@ HandlesView::HandlesView(QWidget* parent) : QWidget(parent)
mTcpConnectionsTable->addColumnAt(8 + 64 * wCharWidth, tr("Local address"), false);
mTcpConnectionsTable->addColumnAt(8 + 8 * wCharWidth, tr("State"), false);
mTcpConnectionsTable->loadColumnFromConfig("TcpConnection");
/*
mHeapsTable = new ReferenceView(this);
mHeapsTable->setWindowTitle("Heaps");
//mHeapsTable->setContextMenuPolicy(Qt::CustomContextMenu);
mHeapsTable->addColumnAt(sizeof(duint) * 2, tr("Address"));
mHeapsTable->addColumnAt(sizeof(duint) * 2, tr("Size"));
mHeapsTable->addColumnAt(20, tr("Flags"));
mHeapsTable->addColumnAt(50, tr("Comments"));
*/
mPrivilegesTable = new StdTable(this);
mPrivilegesTable->setWindowTitle("Privileges");
mPrivilegesTable->setDrawDebugOnly(true);
@ -39,6 +64,8 @@ HandlesView::HandlesView(QWidget* parent) : QWidget(parent)
// Splitter
mSplitter = new LabeledSplitter(this);
mSplitter->addWidget(mHandlesTable, tr("Handles"));
mSplitter->addWidget(mWindowsTable, tr("Windows"));
//mSplitter->addWidget(mHeapsTable, tr("Heaps"));
mSplitter->addWidget(mTcpConnectionsTable, tr("TCP Connections"));
mSplitter->addWidget(mPrivilegesTable, tr("Privileges"));
mSplitter->collapseLowerTabs();
@ -67,6 +94,7 @@ HandlesView::HandlesView(QWidget* parent) : QWidget(parent)
connect(mActionEnableAllPrivileges, SIGNAL(triggered()), this, SLOT(enableAllPrivilegesSlot()));
connect(mHandlesTable, SIGNAL(contextMenuSignal(const QPoint &)), this, SLOT(handlesTableContextMenuSlot(const QPoint &)));
connect(mWindowsTable, SIGNAL(contextMenuSignal(const QPoint &)), this, SLOT(windowsTableContextMenuSlot(const QPoint &)));
connect(mTcpConnectionsTable, SIGNAL(contextMenuSignal(const QPoint &)), this, SLOT(tcpConnectionsTableContextMenuSlot(const QPoint &)));
connect(mPrivilegesTable, SIGNAL(contextMenuSignal(const QPoint &)), this, SLOT(privilegesTableContextMenuSlot(const QPoint &)));
connect(Config(), SIGNAL(shortcutsUpdated()), this, SLOT(refreshShortcuts()));
@ -87,15 +115,21 @@ void HandlesView::reloadData()
if(DbgIsDebugging())
{
enumHandles();
enumWindows();
enumTcpConnections();
//enumHeaps();
enumPrivileges();
}
else
{
mHandlesTable->setRowCount(0);
mHandlesTable->reloadData();
mWindowsTable->setRowCount(0);
mWindowsTable->reloadData();
mTcpConnectionsTable->setRowCount(0);
mTcpConnectionsTable->reloadData();
//mHeapsTable->setRowCount(0);
//mHeapsTable->reloadData();
mPrivilegesTable->setRowCount(0);
mPrivilegesTable->reloadData();
}
@ -114,6 +148,8 @@ void HandlesView::dbgStateChanged(DBGSTATE state)
void HandlesView::handlesTableContextMenuSlot(const QPoint & pos)
{
if(!DbgIsDebugging())
return;
StdTable & table = *mHandlesTable;
QMenu wMenu;
QMenu wCopyMenu(tr("&Copy"), this);
@ -134,8 +170,32 @@ void HandlesView::handlesTableContextMenuSlot(const QPoint & pos)
wMenu.exec(table.mapToGlobal(pos));
}
void HandlesView::windowsTableContextMenuSlot(const QPoint & pos)
{
if(!DbgIsDebugging())
return;
StdTable & table = *mWindowsTable;
QMenu wMenu;
QMenu wCopyMenu(tr("Copy"), this);
wCopyMenu.setIcon(DIcon("copy.png"));
wMenu.addAction(mActionRefresh);
if(table.getRowCount())
{
wMenu.addSeparator();
table.setupCopyMenu(&wCopyMenu);
if(wCopyMenu.actions().length())
{
wMenu.addSeparator();
wMenu.addMenu(&wCopyMenu);
}
}
wMenu.exec(table.mapToGlobal(pos));
}
void HandlesView::tcpConnectionsTableContextMenuSlot(const QPoint & pos)
{
if(!DbgIsDebugging())
return;
StdTable & table = *mTcpConnectionsTable;
QMenu wMenu;
QMenu wCopyMenu(tr("&Copy"), this);
@ -154,9 +214,10 @@ void HandlesView::tcpConnectionsTableContextMenuSlot(const QPoint & pos)
wMenu.exec(table.mapToGlobal(pos));
}
void HandlesView::privilegesTableContextMenuSlot(const QPoint & pos)
{
if(!DbgIsDebugging())
return;
StdTable & table = *mPrivilegesTable;
QMenu wMenu;
bool isValid = (table.getRowCount() != 0 && table.getCellContent(table.getInitialSelection(), 1) != tr("Unknown"));
@ -201,12 +262,16 @@ void HandlesView::enablePrivilegeSlot()
void HandlesView::disablePrivilegeSlot()
{
if(!DbgIsDebugging())
return;
DbgCmdExec(QString("DisablePrivilege \"%1\"").arg(mPrivilegesTable->getCellContent(mPrivilegesTable->getInitialSelection(), 0)).toUtf8().constData());
enumPrivileges();
}
void HandlesView::enableAllPrivilegesSlot()
{
if(!DbgIsDebugging())
return;
for(int i = 0; i < mPrivilegesTable->getRowCount(); i++)
if(mPrivilegesTable->getCellContent(i, 1) != tr("Unknown"))
DbgCmdExec(QString("EnablePrivilege \"%1\"").arg(mPrivilegesTable->getCellContent(i, 0)).toUtf8().constData());
@ -215,12 +280,16 @@ void HandlesView::enableAllPrivilegesSlot()
void HandlesView::disableAllPrivilegesSlot()
{
if(!DbgIsDebugging())
return;
for(int i = 0; i < mPrivilegesTable->getRowCount(); i++)
if(mPrivilegesTable->getCellContent(i, 1) != tr("Unknown"))
DbgCmdExec(QString("DisablePrivilege \"%1\"").arg(mPrivilegesTable->getCellContent(i, 0)).toUtf8().constData());
enumPrivileges();
}
//Enum functions
//Enumerate handles and update handles table
void HandlesView::enumHandles()
{
BridgeList<HANDLEINFO> handles;
@ -245,7 +314,44 @@ void HandlesView::enumHandles()
mHandlesTable->setRowCount(0);
mHandlesTable->reloadData();
}
//Enumerate windows and update windows table
void HandlesView::enumWindows()
{
BridgeList<WINDOW_INFO> windows;
if(DbgFunctions()->EnumWindows(&windows))
{
auto count = windows.Count();
mWindowsTable->setRowCount(count);
for(auto i = 0; i < count; i++)
{
mWindowsTable->setCellContent(i, 0, ToHexString(windows[i].handle));
mWindowsTable->setCellContent(i, 1, QString(windows[i].windowTitle));
mWindowsTable->setCellContent(i, 2, QString(windows[i].windowClass));
char threadname[MAX_THREAD_NAME_SIZE];
if(DbgFunctions()->ThreadGetName(windows[i].threadId, threadname))
mWindowsTable->setCellContent(i, 3, QString::fromUtf8(threadname));
else if(Config()->getBool("Gui", "PidInHex"))
mWindowsTable->setCellContent(i, 3, ToHexString(windows[i].threadId));
else
mWindowsTable->setCellContent(i, 3, QString::number(windows[i].threadId));
//Style
mWindowsTable->setCellContent(i, 4, ToHexString(windows[i].style));
//StyleEx
mWindowsTable->setCellContent(i, 5, ToHexString(windows[i].styleEx));
mWindowsTable->setCellContent(i, 6, ToHexString(windows[i].parent) + (windows[i].parent == ((duint)GetDesktopWindow()) ? tr(" (Desktop window)") : ""));
//Size
QString sizeText = QString("(%1,%2);%3x%4").arg(windows[i].position.left).arg(windows[i].position.top)
.arg(windows[i].position.right - windows[i].position.left).arg(windows[i].position.bottom - windows[i].position.top);
mWindowsTable->setCellContent(i, 7, sizeText);
mWindowsTable->setCellContent(i, 8, windows[i].enabled != FALSE ? tr("Enabled") : tr("Disabled"));
}
}
else
mWindowsTable->setRowCount(0);
mWindowsTable->reloadData();
}
//Enumerate privileges and update privileges table
void HandlesView::enumPrivileges()
{
mPrivilegesTable->setRowCount(35);
@ -305,7 +411,7 @@ void HandlesView::AppendPrivilege(int row, const char* PrivilegeString)
break;
}
}
//Enumerate TCP connections and update TCP connections table
void HandlesView::enumTcpConnections()
{
BridgeList<TCPCONNECTIONINFO> connections;
@ -327,3 +433,47 @@ void HandlesView::enumTcpConnections()
mTcpConnectionsTable->setRowCount(0);
mTcpConnectionsTable->reloadData();
}
/*
//Enumerate Heaps and update Heaps table
void HandlesView::enumHeaps()
{
BridgeList<HEAPINFO> heaps;
if(DbgFunctions()->EnumHeaps(&heaps))
{
auto count = heaps.Count();
mHeapsTable->setRowCount(count);
for(auto i = 0; i < count; i++)
{
const HEAPINFO & heap = heaps[i];
mHeapsTable->setCellContent(i, 0, ToPtrString(heap.addr));
mHeapsTable->setCellContent(i, 1, ToHexString(heap.size));
QString flagsText;
if(heap.flags == 0)
flagsText = " |"; //Always leave 2 characters to be removed
if(heap.flags & 1)
flagsText = "LF32_FIXED |";
if(heap.flags & 2)
flagsText += "LF32_FREE |";
if(heap.flags & 4)
flagsText += "LF32_MOVABLE |";
if(heap.flags & (~7))
flagsText += ToHexString(heap.flags & (~7)) + " |";
flagsText.chop(2); //Remove last 2 characters: " |"
mHeapsTable->setCellContent(i, 2, flagsText);
QString comment;
char commentUtf8[MAX_COMMENT_SIZE];
if(DbgGetCommentAt(heap.addr, commentUtf8))
comment = QString::fromUtf8(commentUtf8);
else
{
if(DbgGetStringAt(heap.addr, commentUtf8))
comment = QString::fromUtf8(commentUtf8);
}
mHeapsTable->setCellContent(i, 3, comment);
}
}
else
mHeapsTable->setRowCount(0);
mHeapsTable->reloadData();
}
*/

View File

@ -5,6 +5,7 @@
#include "Imports.h"
class StdTable;
class ReferenceView;
class QVBoxLayout;
class LabeledSplitter;
@ -21,6 +22,7 @@ public slots:
void handlesTableContextMenuSlot(const QPoint & pos);
void tcpConnectionsTableContextMenuSlot(const QPoint & pos);
void windowsTableContextMenuSlot(const QPoint & pos);
void privilegesTableContextMenuSlot(const QPoint & pos);
void closeHandleSlot();
@ -34,6 +36,8 @@ private:
LabeledSplitter* mSplitter;
StdTable* mHandlesTable;
StdTable* mTcpConnectionsTable;
StdTable* mWindowsTable;
//ReferenceView* mHeapsTable;
StdTable* mPrivilegesTable;
QAction* mActionRefresh;
@ -44,7 +48,9 @@ private:
QAction* mActionEnableAllPrivileges;
void enumHandles();
void enumWindows();
void enumTcpConnections();
//void enumHeaps();
void enumPrivileges();
void AppendPrivilege(int row, const char* PrivilegeString);