mirror of
https://github.com/mirkobrombin/raven.git
synced 2026-11-03 21:46:32 +00:00
59 lines
1.9 KiB
C++
59 lines
1.9 KiB
C++
#include "api.h"
|
|
|
|
#include <new>
|
|
#include <stdexcept>
|
|
|
|
namespace raven {
|
|
|
|
uint64_t NativeDesktop::menu_resource(uint64_t instance,uint64_t identifier)
|
|
{
|
|
const auto view=resources.view(instance,4,identifier);
|
|
if (!view || view->size>1024*1024) return 0;
|
|
try {
|
|
return objects.load_menu(decode_menu(process.read_memory(view->address,view->size)));
|
|
} catch (const std::runtime_error &) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
bool NativeDesktop::menu_dispatch(std::string_view name)
|
|
{
|
|
const bool load=name=="LoadMenuW",count=name=="GetMenuItemCount",id=name=="GetMenuItemID",sub=name=="GetSubMenu";
|
|
if (!load && !count && !id && !sub && name!="DestroyMenu" && name!="IsMenu") return false;
|
|
const auto args=process.api_arguments(load || id || sub ? 2 : 1);
|
|
uint64_t result=count || id ? UINT32_MAX : 0;
|
|
try {
|
|
if (load) {
|
|
const auto view=resources.view(args[0],4,args[1]);
|
|
if (view) {
|
|
if (view->size>1024*1024) throw uint32_t(120);
|
|
const auto bytes=process.read_memory(view->address,view->size);
|
|
MenuTemplate definition;
|
|
try { definition=decode_menu(bytes); }
|
|
catch (const std::runtime_error &) { throw uint32_t(13); }
|
|
result=objects.load_menu(definition);
|
|
}
|
|
} else {
|
|
const auto *menu=objects.menu(args[0]);
|
|
if (name=="IsMenu") result=menu!=nullptr;
|
|
else if (menu && count) result=menu->items.size();
|
|
else if (menu && name=="DestroyMenu") {
|
|
// Attached submenu mutation needs the parent-item transition contract.
|
|
if (menu->parent) throw uint32_t(120);
|
|
result=objects.erase(args[0]);
|
|
} else if (menu) {
|
|
const auto position=int32_t(uint32_t(args[1]));
|
|
if (position>=0 && size_t(position)<menu->items.size()) {
|
|
const auto &item=menu->items[size_t(position)];
|
|
result=sub ? item.submenu : item.submenu ? UINT32_MAX : item.id;
|
|
}
|
|
}
|
|
}
|
|
} catch (uint32_t error) { environment.set_last_error(error); }
|
|
catch (const std::bad_alloc &) { environment.set_last_error(8); }
|
|
process.return_api(result);
|
|
return true;
|
|
}
|
|
|
|
}
|