XModule Save/Restore
This commit is contained in:
parent
93602ed48a
commit
4a3773d2fb
|
@ -304,6 +304,38 @@ object_ref<XThread> UserModule::Launch(uint32_t flags) {
|
||||||
return thread;
|
return thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool UserModule::Save(ByteStream* stream) {
|
||||||
|
if (!XModule::Save(stream)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// A lot of the information stored on this class can be reconstructed at
|
||||||
|
// runtime.
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
object_ref<UserModule> UserModule::Restore(KernelState* kernel_state,
|
||||||
|
ByteStream* stream,
|
||||||
|
std::string path) {
|
||||||
|
auto module = new UserModule(kernel_state, path.c_str());
|
||||||
|
|
||||||
|
// XModule::Save took care of this earlier...
|
||||||
|
// TODO: Find a nicer way to represent that here.
|
||||||
|
if (!module->RestoreObject(stream)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto result = module->LoadFromFile(path);
|
||||||
|
if (XFAILED(result)) {
|
||||||
|
XELOGD("UserModule::Restore LoadFromFile(%s) FAILED - code %.8X",
|
||||||
|
path.c_str(), result);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return object_ref<UserModule>(module);
|
||||||
|
}
|
||||||
|
|
||||||
void UserModule::Dump() {
|
void UserModule::Dump() {
|
||||||
if (module_format_ == kModuleFormatElf) {
|
if (module_format_ == kModuleFormatElf) {
|
||||||
// Quick die.
|
// Quick die.
|
||||||
|
|
|
@ -87,6 +87,10 @@ class UserModule : public XModule {
|
||||||
|
|
||||||
void Dump();
|
void Dump();
|
||||||
|
|
||||||
|
bool Save(ByteStream* stream) override;
|
||||||
|
static object_ref<UserModule> Restore(KernelState* kernel_state,
|
||||||
|
ByteStream* stream, std::string path);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t guest_xex_header_ = 0;
|
uint32_t guest_xex_header_ = 0;
|
||||||
ModuleFormat module_format_ = kModuleFormatUndefined;
|
ModuleFormat module_format_ = kModuleFormatUndefined;
|
||||||
|
|
|
@ -9,8 +9,10 @@
|
||||||
|
|
||||||
#include "xenia/kernel/xmodule.h"
|
#include "xenia/kernel/xmodule.h"
|
||||||
|
|
||||||
|
#include "xenia/base/byte_stream.h"
|
||||||
#include "xenia/base/string.h"
|
#include "xenia/base/string.h"
|
||||||
#include "xenia/kernel/kernel_state.h"
|
#include "xenia/kernel/kernel_state.h"
|
||||||
|
#include "xenia/kernel/user_module.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
|
@ -22,19 +24,7 @@ XModule::XModule(KernelState* kernel_state, ModuleType module_type,
|
||||||
path_(path),
|
path_(path),
|
||||||
processor_module_(nullptr),
|
processor_module_(nullptr),
|
||||||
hmodule_ptr_(0) {
|
hmodule_ptr_(0) {
|
||||||
auto last_slash = path.find_last_of('/');
|
name_ = NameFromPath(path);
|
||||||
if (last_slash == path.npos) {
|
|
||||||
last_slash = path.find_last_of('\\');
|
|
||||||
}
|
|
||||||
if (last_slash == path.npos) {
|
|
||||||
name_ = path_;
|
|
||||||
} else {
|
|
||||||
name_ = path_.substr(last_slash + 1);
|
|
||||||
}
|
|
||||||
auto dot = name_.find_last_of('.');
|
|
||||||
if (dot != name_.npos) {
|
|
||||||
name_ = name_.substr(0, dot);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Loader data (HMODULE)
|
// Loader data (HMODULE)
|
||||||
hmodule_ptr_ = memory()->SystemHeapAlloc(sizeof(X_LDR_DATA_TABLE_ENTRY));
|
hmodule_ptr_ = memory()->SystemHeapAlloc(sizeof(X_LDR_DATA_TABLE_ENTRY));
|
||||||
|
@ -86,5 +76,54 @@ uint32_t XModule::GetHandleFromHModule(void* hmodule) {
|
||||||
return ldr_data->checksum;
|
return ldr_data->checksum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string XModule::NameFromPath(std::string path) {
|
||||||
|
std::string name;
|
||||||
|
auto last_slash = path.find_last_of('/');
|
||||||
|
if (last_slash == path.npos) {
|
||||||
|
last_slash = path.find_last_of('\\');
|
||||||
|
}
|
||||||
|
if (last_slash == path.npos) {
|
||||||
|
name = path;
|
||||||
|
} else {
|
||||||
|
name = path.substr(last_slash + 1);
|
||||||
|
}
|
||||||
|
auto dot = name.find_last_of('.');
|
||||||
|
if (dot != name.npos) {
|
||||||
|
name = name.substr(0, dot);
|
||||||
|
}
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool XModule::Save(ByteStream* stream) {
|
||||||
|
stream->Write('XMOD');
|
||||||
|
|
||||||
|
stream->Write(path_);
|
||||||
|
stream->Write(hmodule_ptr_);
|
||||||
|
|
||||||
|
if (!SaveObject(stream)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
object_ref<XModule> XModule::Restore(KernelState* kernel_state,
|
||||||
|
ByteStream* stream) {
|
||||||
|
if (stream->Read<uint32_t>() != 'XMOD') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto path = stream->Read<std::string>();
|
||||||
|
auto hmodule_ptr = stream->Read<uint32_t>();
|
||||||
|
|
||||||
|
// Can only save user modules at the moment, so just redirect.
|
||||||
|
// TODO: Find a way to call RestoreObject here before UserModule::Restore.
|
||||||
|
auto module = UserModule::Restore(kernel_state, stream, path);
|
||||||
|
|
||||||
|
module->hmodule_ptr_ = hmodule_ptr;
|
||||||
|
return module;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace kernel
|
} // namespace kernel
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
|
@ -80,9 +80,13 @@ class XModule : public XObject {
|
||||||
void* hmodule);
|
void* hmodule);
|
||||||
static uint32_t GetHandleFromHModule(void* hmodule);
|
static uint32_t GetHandleFromHModule(void* hmodule);
|
||||||
|
|
||||||
|
virtual bool Save(ByteStream* stream) override;
|
||||||
|
static object_ref<XModule> Restore(KernelState* kernel_state, ByteStream* stream);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void OnLoad();
|
void OnLoad();
|
||||||
void OnUnload();
|
void OnUnload();
|
||||||
|
static std::string NameFromPath(std::string path);
|
||||||
|
|
||||||
ModuleType module_type_;
|
ModuleType module_type_;
|
||||||
std::string name_;
|
std::string name_;
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "xenia/kernel/xenumerator.h"
|
#include "xenia/kernel/xenumerator.h"
|
||||||
#include "xenia/kernel/xevent.h"
|
#include "xenia/kernel/xevent.h"
|
||||||
#include "xenia/kernel/xfile.h"
|
#include "xenia/kernel/xfile.h"
|
||||||
|
#include "xenia/kernel/xmodule.h"
|
||||||
#include "xenia/kernel/xmutant.h"
|
#include "xenia/kernel/xmutant.h"
|
||||||
#include "xenia/kernel/xsemaphore.h"
|
#include "xenia/kernel/xsemaphore.h"
|
||||||
#include "xenia/kernel/xthread.h"
|
#include "xenia/kernel/xthread.h"
|
||||||
|
@ -129,7 +130,7 @@ object_ref<XObject> XObject::Restore(KernelState* kernel_state, Type type,
|
||||||
case kTypeIOCompletion:
|
case kTypeIOCompletion:
|
||||||
break;
|
break;
|
||||||
case kTypeModule:
|
case kTypeModule:
|
||||||
break;
|
return XModule::Restore(kernel_state, stream);
|
||||||
case kTypeMutant:
|
case kTypeMutant:
|
||||||
break;
|
break;
|
||||||
case kTypeNotifyListener:
|
case kTypeNotifyListener:
|
||||||
|
|
Loading…
Reference in New Issue