1
0
Fork 0

BRIDGE: added menu API

DBG: added menu API
GUI: changed bridge result variable behavior
GUI: added menu API
This commit is contained in:
mr.exodia 2014-04-18 22:37:54 +02:00
parent d340ec6ae1
commit f17afa0ea7
8 changed files with 300 additions and 11 deletions

View File

@ -580,6 +580,11 @@ BRIDGE_IMPEXP void DbgDisasmFastAt(duint addr, BASIC_INSTRUCTION_INFO* basicinfo
_dbg_sendmessage(DBG_DISASM_FAST_AT, (void*)addr, basicinfo);
}
BRIDGE_IMPEXP void DbgMenuEntryClicked(int hEntry)
{
_dbg_sendmessage(DBG_MENU_ENTRY_CLICKED, (void*)(duint)hEntry, 0);
}
//GUI
BRIDGE_IMPEXP void GuiDisasmAt(duint addr, duint cip)
{
@ -784,6 +789,26 @@ BRIDGE_IMPEXP bool GuiGetDisassembly(duint addr, char* text)
return (bool)(duint)_gui_sendmessage(GUI_GET_DISASSEMBLY, (void*)addr, text);
}
BRIDGE_IMPEXP int GuiMenuAdd(int hMenu, const char* title)
{
return (int)(duint)_gui_sendmessage(GUI_MENU_ADD, (void*)(duint)hMenu, (void*)title);
}
BRIDGE_IMPEXP int GuiMenuAddEntry(int hMenu, const char* title)
{
return (int)(duint)_gui_sendmessage(GUI_MENU_ADD_ENTRY, (void*)(duint)hMenu, (void*)title);
}
BRIDGE_IMPEXP void GuiMenuAddSeparator(int hMenu)
{
_gui_sendmessage(GUI_MENU_ADD_SEPARATOR, (void*)(duint)hMenu, 0);
}
BRIDGE_IMPEXP void GuiMenuClear(int hMenu)
{
_gui_sendmessage(GUI_MENU_CLEAR, (void*)(duint)hMenu, 0);
}
//Main
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{

View File

@ -124,7 +124,8 @@ enum DBGMSG
DBG_STACK_COMMENT_GET, // param1=duint addr, param2=STACK_COMMENT* comment
DBG_GET_THREAD_LIST, // param1=THREADALLINFO* list, param2=unused
DBG_SETTINGS_UPDATED, // param1=unused, param2=unused
DBG_DISASM_FAST_AT // param1=duint addr, param2=BASIC_INSTRUCTION_INFO* basicinfo
DBG_DISASM_FAST_AT, // param1=duint addr, param2=BASIC_INSTRUCTION_INFO* basicinfo
DBG_MENU_ENTRY_CLICKED // param1=int hEntry, param2=unused
};
enum SCRIPTLINETYPE
@ -461,6 +462,10 @@ BRIDGE_IMPEXP bool DbgStackCommentGet(duint addr, STACK_COMMENT* comment);
BRIDGE_IMPEXP void DbgGetThreadList(THREADLIST* list);
BRIDGE_IMPEXP void DbgSettingsUpdated();
BRIDGE_IMPEXP void DbgDisasmFastAt(duint addr, BASIC_INSTRUCTION_INFO* basicinfo);
BRIDGE_IMPEXP void DbgMenuEntryClicked(int hEntry);
//Gui defines
#define GUI_PLUGIN_MENU 0
//Gui enums
enum GUIMSG
@ -502,7 +507,11 @@ enum GUIMSG
GUI_UPDATE_THREAD_VIEW, // param1=unused, param2=unused
GUI_ADD_RECENT_FILE, // param1=(const char*)file, param2=unused
GUI_SET_LAST_EXCEPTION, // param1=unsigned int code, param2=unused
GUI_GET_DISASSEMBLY // param1=duint addr, param2=char* text
GUI_GET_DISASSEMBLY, // param1=duint addr, param2=char* text
GUI_MENU_ADD, // param1=int hMenu, param2=const char* title
GUI_MENU_ADD_ENTRY, // param1=int hMenu, param2=const char* title
GUI_MENU_ADD_SEPARATOR, // param1=int hMenu, param2=unused
GUI_MENU_CLEAR // param1=int hMenu, param2=unused
};
//GUI structures
@ -553,6 +562,10 @@ BRIDGE_IMPEXP void GuiUpdateThreadView();
BRIDGE_IMPEXP void GuiAddRecentFile(const char* file);
BRIDGE_IMPEXP void GuiSetLastException(unsigned int exception);
BRIDGE_IMPEXP bool GuiGetDisassembly(duint addr, char* text);
BRIDGE_IMPEXP int GuiMenuAdd(int hMenu, const char* title);
BRIDGE_IMPEXP int GuiMenuAddEntry(int hMenu, const char* title);
BRIDGE_IMPEXP void GuiMenuAddSeparator(int hMenu);
BRIDGE_IMPEXP void GuiMenuClear(int hMenu);
#ifdef __cplusplus
}

View File

@ -709,6 +709,12 @@ extern "C" DLL_EXPORT uint _dbg_sendmessage(DBGMSG type, void* param1, void* par
fillbasicinfo(&disasm, (BASIC_INSTRUCTION_INFO*)param2);
}
break;
case DBG_MENU_ENTRY_CLICKED:
{
int hEntry=(int)(uint)param1;
}
break;
}
return 0;
}

View File

@ -186,7 +186,7 @@ void ScriptView::add(int count, const char** lines)
setCellContent(i, 1, QString(lines[i]));
BridgeFree(lines);
reloadData(); //repaint
Bridge::getBridge()->scriptResult=1;
Bridge::getBridge()->BridgeSetResult(1);
}
void ScriptView::clear()
@ -329,7 +329,7 @@ void ScriptView::question(QString message)
msg.setParent(this, Qt::Dialog);
msg.setWindowFlags(msg.windowFlags()&(~Qt::WindowContextHelpButtonHint));
if(msg.exec()==QMessageBox::Yes)
Bridge::getBridge()->scriptResult=1;
Bridge::getBridge()->BridgeSetResult(1);
else
Bridge::getBridge()->scriptResult=0;
Bridge::getBridge()->BridgeSetResult(0);
}

View File

@ -34,6 +34,12 @@ void Bridge::CopyToClipboard(const char* text)
CloseClipboard();
}
void Bridge::BridgeSetResult(int_t result)
{
bridgeResult=result;
hasBridgeResult=true;
}
/************************************************************************************
Exports Binding
************************************************************************************/
@ -85,9 +91,9 @@ void Bridge::emitDumpAt(int_t va)
void Bridge::emitScriptAdd(int count, const char** lines)
{
mBridgeMutex.lock();
scriptResult=-1;
hasBridgeResult=false;
emit scriptAdd(count, lines);
while(scriptResult==-1) //wait for thread completion
while(!hasBridgeResult) //wait for thread completion
Sleep(100);
mBridgeMutex.unlock();
}
@ -125,12 +131,12 @@ void Bridge::emitScriptMessage(QString message)
int Bridge::emitScriptQuestion(QString message)
{
mBridgeMutex.lock();
scriptResult=-1;
hasBridgeResult=false;
emit scriptQuestion(message);
while(scriptResult==-1) //wait for thread completion
while(!hasBridgeResult) //wait for thread completion
Sleep(100);
mBridgeMutex.unlock();
return scriptResult;
return bridgeResult;
}
void Bridge::emitUpdateSymbolList(int module_count, SYMBOLMODULEINFO* modules)
@ -218,6 +224,38 @@ void Bridge::emitSetLastException(unsigned int exceptionCode)
emit setLastException(exceptionCode);
}
int Bridge::emitMenuAddMenu(int hMenu, QString title)
{
mBridgeMutex.lock();
hasBridgeResult=false;
emit menuAddMenu(hMenu, title);
while(!hasBridgeResult) //wait for thread completion
Sleep(100);
mBridgeMutex.unlock();
return bridgeResult;
}
int Bridge::emitMenuAddMenuEntry(int hMenu, QString title)
{
mBridgeMutex.lock();
hasBridgeResult=false;
emit menuAddMenuEntry(hMenu, title);
while(!hasBridgeResult) //wait for thread completion
Sleep(100);
mBridgeMutex.unlock();
return bridgeResult;
}
void Bridge::emitMenuAddSeparator(int hMenu)
{
emit menuAddSeparator(hMenu);
}
void Bridge::emitMenuClearMenu(int hMenu)
{
emit menuClearMenu(hMenu);
}
/************************************************************************************
Static Functions
************************************************************************************/
@ -487,6 +525,30 @@ __declspec(dllexport) void* _gui_sendmessage(GUIMSG type, void* param1, void* pa
}
break;
case GUI_MENU_ADD:
{
return (void*)(uint_t)Bridge::getBridge()->emitMenuAddMenu((int)(uint_t)param1, QString(reinterpret_cast<const char*>(param2)));
}
break;
case GUI_MENU_ADD_ENTRY:
{
return (void*)(uint_t)Bridge::getBridge()->emitMenuAddMenuEntry((int)(uint_t)param1, QString(reinterpret_cast<const char*>(param2)));
}
break;
case GUI_MENU_ADD_SEPARATOR:
{
Bridge::getBridge()->emitMenuAddSeparator((int)(uint_t)param1);
}
break;
case GUI_MENU_CLEAR:
{
Bridge::getBridge()->emitMenuClearMenu((int)(uint_t)param1);
}
break;
default:
{
}

View File

@ -26,6 +26,9 @@ public:
// Misc functions
static void CopyToClipboard(const char* text);
//result function
void BridgeSetResult(int_t result);
// Exports Binding
void emitDisassembleAtSignal(int_t va, int_t eip);
void emitUpdateDisassembly();
@ -61,12 +64,15 @@ public:
void emitUpdateThreads();
void emitAddRecentFile(QString file);
void emitSetLastException(unsigned int exceptionCode);
int emitMenuAddMenu(int hMenu, QString title);
int emitMenuAddMenuEntry(int hMenu, QString title);
void emitMenuAddSeparator(int hMenu);
void emitMenuClearMenu(int hMenu);
//Public variables
void* winId;
QWidget* scriptView;
SearchListView* referenceView;
int scriptResult;
signals:
void disassembleAt(int_t va, int_t eip);
@ -103,9 +109,15 @@ signals:
void updateThreads();
void addRecentFile(QString file);
void setLastException(unsigned int exceptionCode);
void menuAddMenu(int hMenu, QString title);
void menuAddMenuEntry(int hMenu, QString title);
void menuAddSeparator(int hMenu);
void menuClearMenu(int hMenu);
private:
QMutex mBridgeMutex;
int_t bridgeResult;
bool hasBridgeResult;
public:

View File

@ -132,12 +132,19 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
connect(Bridge::getBridge(), SIGNAL(updateWindowTitle(QString)), this, SLOT(updateWindowTitleSlot(QString)));
connect(Bridge::getBridge(), SIGNAL(addRecentFile(QString)), this, SLOT(addRecentFile(QString)));
connect(Bridge::getBridge(), SIGNAL(setLastException(uint)), this, SLOT(setLastException(uint)));
connect(Bridge::getBridge(), SIGNAL(menuAddMenu(int,QString)), this, SLOT(addMenu(int,QString)));
connect(Bridge::getBridge(), SIGNAL(menuAddMenuEntry(int,QString)), this, SLOT(addMenuEntry(int,QString)));
connect(Bridge::getBridge(), SIGNAL(menuAddSeparator(int)), this, SLOT(addSeparator(int)));
connect(Bridge::getBridge(), SIGNAL(menuClearMenu(int)), this, SLOT(clearMenu(int)));
//Set default setttings (when not set)
SettingsDialog defaultSettings;
lastException=0;
defaultSettings.SaveSettings();
//setup menu api
initMenuApi();
const char* errormsg=DbgInit();
if(errormsg)
{
@ -536,3 +543,140 @@ void MainWindow::findStrings()
DbgCmdExec("strref");
displayReferencesWidget();
}
void MainWindow::addMenu(int hMenu, QString title)
{
int nFound=-1;
for(int i=0; i<mMenuList.size(); i++)
{
if(hMenu==mMenuList.at(i).hMenu)
{
nFound=i;
break;
}
}
if(nFound==-1 && hMenu!=-1)
{
Bridge::getBridge()->BridgeSetResult(-1);
return;
}
MenuInfo newInfo;
int hMenuNew=hMenuNext;
hMenuNext++;
QMenu* wMenu = new QMenu(title, this);
newInfo.mMenu=wMenu;
newInfo.hMenu=hMenuNew;
newInfo.hParentMenu=hMenu;
mMenuList.push_back(newInfo);
if(hMenu==-1) //top-level
ui->menuBar->addMenu(wMenu);
else //deeper level
mMenuList.at(nFound).mMenu->addMenu(wMenu);
Bridge::getBridge()->BridgeSetResult(hMenuNew);
}
void MainWindow::addMenuEntry(int hMenu, QString title)
{
int nFound=-1;
for(int i=0; i<mMenuList.size(); i++)
{
if(hMenu==mMenuList.at(i).hMenu)
{
nFound=i;
break;
}
}
if(nFound==-1 && hMenu!=-1)
{
Bridge::getBridge()->BridgeSetResult(-1);
return;
}
MenuEntryInfo newInfo;
int hEntryNew=hEntryNext;
hEntryNext++;
newInfo.hEntry=hEntryNew;
newInfo.hParentMenu=hMenu;
QAction* wAction = new QAction(title, this);
wAction->setObjectName(QString().sprintf("ENTRY|%d", hEntryNew));
this->addAction(wAction);
connect(wAction, SIGNAL(triggered()), this, SLOT(menuEntrySlot()));
newInfo.mAction=wAction;
mEntryList.push_back(newInfo);
if(hMenu==-1) //top level
ui->menuBar->addAction(wAction);
else //deeper level
mMenuList.at(nFound).mMenu->addAction(wAction);
Bridge::getBridge()->BridgeSetResult(hEntryNew);
}
void MainWindow::addSeparator(int hMenu)
{
int nFound=-1;
for(int i=0; i<mMenuList.size(); i++)
{
if(hMenu==mMenuList.at(i).hMenu) //we found a menu that has the menu as parent
{
nFound=i;
break;
}
}
if(nFound==-1) //not found
return;
MenuEntryInfo newInfo;
newInfo.hEntry=-1;
newInfo.hParentMenu=hMenu;
newInfo.mAction=mMenuList.at(nFound).mMenu->addSeparator();
mEntryList.push_back(newInfo);
}
void MainWindow::clearMenu(int hMenu)
{
if(!mMenuList.size() || hMenu==-1)
return;
//delete menu entries
for(int i=mEntryList.size()-1; i>-1; i--)
{
if(hMenu==mEntryList.at(i).hParentMenu) //we found an entry that has the menu as parent
{
this->removeAction(mEntryList.at(i).mAction);
delete mEntryList.at(i).mAction; //delete the entry object
mEntryList.erase(mEntryList.begin()+i);
}
}
//recursively delete the menus
for(int i=mMenuList.size()-1; i>-1; i--)
{
if(hMenu==mMenuList.at(i).hParentMenu) //we found a menu that has the menu as parent
{
clearMenu(mMenuList.at(i).hMenu); //delete children menus
delete mMenuList.at(i).mMenu; //delete the child menu object
mMenuList.erase(mMenuList.begin()+i); //delete the child entry
}
}
}
void MainWindow::initMenuApi()
{
//256 entries are reserved
mEntryList.clear();
hEntryNext = 256;
mMenuList.clear();
hMenuNext = 256;
MenuInfo newInfo;
//add plugin menu
newInfo.mMenu=ui->menuPlugins;
newInfo.hMenu=GUI_PLUGIN_MENU;
newInfo.hParentMenu=-1;
mMenuList.push_back(newInfo);
}
void MainWindow::menuEntrySlot()
{
QAction* action = qobject_cast<QAction*>(sender());
if(action && action->objectName().startsWith("ENTRY|"))
{
int hEntry = -1;
if(sscanf(action->objectName().mid(6).toUtf8().constData(), "%d", &hEntry)==1)
DbgMenuEntryClicked(hEntry);
}
}

View File

@ -61,6 +61,11 @@ public slots:
void addRecentFile(QString file);
void setLastException(unsigned int exceptionCode);
void findStrings();
void addMenu(int hMenu, QString title);
void addMenuEntry(int hMenu, QString title);
void addSeparator(int hMenu);
void clearMenu(int hMenu);
void menuEntrySlot();
private:
Ui::MainWindow *ui;
@ -92,6 +97,28 @@ private:
void updateMRUMenu();
QString getMRUEntry(size_t index);
//menu api
struct MenuEntryInfo
{
QAction* mAction;
int hEntry;
int hParentMenu;
};
struct MenuInfo
{
QMenu* mMenu;
int hMenu;
int hParentMenu;
};
QList<MenuEntryInfo> mEntryList;
int hEntryNext;
QList<MenuInfo> mMenuList;
int hMenuNext;
void initMenuApi();
protected:
void dragEnterEvent(QDragEnterEvent* pEvent);
void dropEvent(QDropEvent* pEvent);