BRIDGE: added menu API
DBG: added menu API GUI: changed bridge result variable behavior GUI: added menu API
This commit is contained in:
parent
d340ec6ae1
commit
f17afa0ea7
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue