static void thread_safe_jump_to(ea_t a) { struct uireq_jumpto_t: public ui_request_t { uireq_jumpto_t(ea_t a) { la = a; } virtual bool idaapi run() { if (qira_address != la) { set_qira_address(la); jumpto(la, -1, 0); // don't UIJMP_ACTIVATE to not steal focus } return false; } ea_t la; }; execute_ui_requests(new uireq_jumpto_t(a), NULL); }
//-------------------------------------------------------------------------- void idaapi run(int /*arg*/) { class msg_req_t: public ui_request_t { const char *_msg; public: msg_req_t(const char *msg): _msg(qstrdup(msg)) { } ~msg_req_t() { qfree((void *)_msg); } virtual bool idaapi run() { msg("%s", _msg); return false; } }; class stepover_req_t: public ui_request_t { int count; public: stepover_req_t(int cnt): count(cnt) { } virtual bool idaapi run() { process_ui_action("ThreadStepOver"); return --count != 0; } }; execute_ui_requests( new msg_req_t("will "), new msg_req_t("step "), new msg_req_t("over 5 times\n"), new stepover_req_t(5), NULL); }
//--------------------------------------------------------------------------- void install_x86seh_menu() { // HACK: We queue this request because commdbg apparently enables the debug menus // just after calling init_debugger(). struct uireq_install_menu_t: public ui_request_t { virtual bool idaapi run() { if ( !inf.is_64bit() ) seh_menu_added = add_menu_item( "Debugger/Debugger windows/Stack trace", "SEH list", "", SETMENU_APP, show_window, NULL); return false; } }; req_id = execute_ui_requests(new uireq_install_menu_t, NULL); }
/* #<pydoc> def execute_ui_requests(callable_list): """ Inserts a list of callables into the UI message processing queue. When the UI is ready it will call one callable. A callable can request to be called more than once if it returns True. @param callable_list: A list of python callable objects. @note: A callable should return True if it wants to be called more than once. @return: Boolean. False if the list contains a non callabale item """ pass #</pydoc> */ static bool py_execute_ui_requests(PyObject *py_list) { struct py_ui_request_t: public ui_request_t { private: ref_vec_t py_callables; size_t py_callable_idx; static int idaapi s_py_list_walk_cb( const ref_t &py_item, Py_ssize_t index, void *ud) { PYW_GIL_CHECK_LOCKED_SCOPE(); // Not callable? Terminate iteration if ( !PyCallable_Check(py_item.o) ) return CIP_FAILED; // Append this callable and increment its reference py_ui_request_t *_this = (py_ui_request_t *)ud; _this->py_callables.push_back(py_item); return CIP_OK; } public: py_ui_request_t(): py_callable_idx(0) { } virtual bool idaapi run() { PYW_GIL_GET; // Get callable ref_t py_callable = py_callables.at(py_callable_idx); bool reschedule; newref_t py_result(PyObject_CallFunctionObjArgs(py_callable.o, NULL)); reschedule = py_result != NULL && PyObject_IsTrue(py_result.o); // No rescheduling? Then advance to the next callable if ( !reschedule ) ++py_callable_idx; // Reschedule this C callback only if there are more callables return py_callable_idx < py_callables.size(); } // Walk the list and extract all callables bool init(PyObject *py_list) { Py_ssize_t count = pyvar_walk_list( py_list, s_py_list_walk_cb, this); return count > 0; } virtual idaapi ~py_ui_request_t() { py_callables.clear(); } }; py_ui_request_t *req = new py_ui_request_t(); if ( !req->init(py_list) ) { delete req; return false; } execute_ui_requests(req, NULL); return true; }