parent
f07d620553
commit
c2e2b3380e
|
@ -25,11 +25,52 @@ namespace kernel {
|
|||
|
||||
using namespace xe::kernel::fs;
|
||||
|
||||
// TODO(benvanik): replace X_OBJECT_ATTRIBUTES with new style and remove this.
|
||||
class X_ANSI_STRING_OLD {
|
||||
private:
|
||||
uint16_t length;
|
||||
uint16_t maximum_length;
|
||||
const char* buffer;
|
||||
|
||||
public:
|
||||
X_ANSI_STRING_OLD() { Zero(); }
|
||||
X_ANSI_STRING_OLD(const uint8_t* base, uint32_t p) { Read(base, p); }
|
||||
void Read(const uint8_t* base, uint32_t p) {
|
||||
length = xe::load_and_swap<uint16_t>(base + p);
|
||||
maximum_length = xe::load_and_swap<uint16_t>(base + p + 2);
|
||||
if (maximum_length) {
|
||||
buffer = (const char*)(base + xe::load_and_swap<uint32_t>(base + p + 4));
|
||||
} else {
|
||||
buffer = 0;
|
||||
}
|
||||
}
|
||||
void Zero() {
|
||||
length = maximum_length = 0;
|
||||
buffer = 0;
|
||||
}
|
||||
char* Duplicate() {
|
||||
if (!buffer || !length) {
|
||||
return nullptr;
|
||||
}
|
||||
auto copy = (char*)calloc(length + 1, sizeof(char));
|
||||
std::strncpy(copy, buffer, length);
|
||||
return copy;
|
||||
}
|
||||
std::string to_string() {
|
||||
if (!buffer || !length) {
|
||||
return "";
|
||||
}
|
||||
std::string result(buffer, length);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
// static_assert_size(X_ANSI_STRING, 8);
|
||||
|
||||
class X_OBJECT_ATTRIBUTES {
|
||||
public:
|
||||
uint32_t root_directory;
|
||||
uint32_t object_name_ptr;
|
||||
X_ANSI_STRING object_name;
|
||||
X_ANSI_STRING_OLD object_name;
|
||||
uint32_t attributes;
|
||||
|
||||
X_OBJECT_ATTRIBUTES() { Zero(); }
|
||||
|
@ -51,7 +92,6 @@ class X_OBJECT_ATTRIBUTES {
|
|||
attributes = 0;
|
||||
}
|
||||
};
|
||||
static_assert_size(X_OBJECT_ATTRIBUTES, 12 + sizeof(X_ANSI_STRING));
|
||||
|
||||
struct FileDisposition {
|
||||
static const uint32_t X_FILE_SUPERSEDE = 0x00000000;
|
||||
|
@ -699,22 +739,17 @@ SHIM_CALL NtQueryDirectoryFile_shim(PPCContext* ppc_context,
|
|||
uint32_t file_name_ptr = SHIM_GET_ARG_32(7);
|
||||
uint32_t restart_scan = SHIM_GET_ARG_32(8);
|
||||
|
||||
char* file_name = NULL;
|
||||
if (file_name_ptr != 0) {
|
||||
X_ANSI_STRING xas(SHIM_MEM_BASE, file_name_ptr);
|
||||
file_name = xas.Duplicate();
|
||||
}
|
||||
auto file_name = X_ANSI_STRING::to_string(SHIM_MEM_BASE, file_name_ptr);
|
||||
|
||||
XELOGD(
|
||||
"NtQueryDirectoryFile(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X, %d, %.8X(%s), "
|
||||
"%d)",
|
||||
file_handle, event_handle, apc_routine, apc_context, io_status_block_ptr,
|
||||
file_info_ptr, length, file_name_ptr, !file_name ? "(null)" : file_name,
|
||||
restart_scan);
|
||||
file_info_ptr, length, file_name_ptr,
|
||||
!file_name.empty() ? file_name.c_str() : "(null)", restart_scan);
|
||||
|
||||
if (length < 72) {
|
||||
SHIM_SET_RETURN_32(X_STATUS_INFO_LENGTH_MISMATCH);
|
||||
free(file_name);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -725,8 +760,8 @@ SHIM_CALL NtQueryDirectoryFile_shim(PPCContext* ppc_context,
|
|||
if (file) {
|
||||
X_FILE_DIRECTORY_INFORMATION* dir_info =
|
||||
(X_FILE_DIRECTORY_INFORMATION*)calloc(length, 1);
|
||||
result =
|
||||
file->QueryDirectory(dir_info, length, file_name, restart_scan != 0);
|
||||
result = file->QueryDirectory(dir_info, length, file_name.c_str(),
|
||||
restart_scan != 0);
|
||||
if (XSUCCEEDED(result)) {
|
||||
dir_info->Write(SHIM_MEM_BASE, file_info_ptr);
|
||||
info = length;
|
||||
|
@ -744,7 +779,6 @@ SHIM_CALL NtQueryDirectoryFile_shim(PPCContext* ppc_context,
|
|||
SHIM_SET_MEM_32(io_status_block_ptr + 4, info); // Information
|
||||
}
|
||||
|
||||
free(file_name);
|
||||
SHIM_SET_RETURN_32(result);
|
||||
}
|
||||
|
||||
|
|
|
@ -33,9 +33,8 @@ SHIM_CALL ObOpenObjectByName_shim(PPCContext* ppc_context,
|
|||
uint32_t unk = SHIM_GET_ARG_32(2);
|
||||
uint32_t handle_ptr = SHIM_GET_ARG_32(3);
|
||||
|
||||
uint32_t name_str_ptr = SHIM_MEM_32(obj_attributes_ptr + 4);
|
||||
X_ANSI_STRING name_str(SHIM_MEM_BASE, name_str_ptr);
|
||||
auto name = name_str.to_string();
|
||||
auto name =
|
||||
X_ANSI_STRING::to_string_indirect(SHIM_MEM_BASE, obj_attributes_ptr + 4);
|
||||
|
||||
XELOGD("ObOpenObjectByName(%.8X(name=%s), %.8X, %.8X, %.8X)",
|
||||
obj_attributes_ptr, name.c_str(), object_type_ptr, unk, handle_ptr);
|
||||
|
|
|
@ -70,12 +70,9 @@ void AssertNoNameCollision(KernelState* kernel_state,
|
|||
if (!obj_attributes_ptr) {
|
||||
return;
|
||||
}
|
||||
uint32_t name_str_ptr = xe::load_and_swap<uint32_t>(
|
||||
kernel_state->memory()->TranslateVirtual(obj_attributes_ptr + 4));
|
||||
if (name_str_ptr) {
|
||||
X_ANSI_STRING name_str(kernel_state->memory()->virtual_membase(),
|
||||
name_str_ptr);
|
||||
auto name = name_str.to_string();
|
||||
auto name = X_ANSI_STRING::to_string_indirect(
|
||||
kernel_state->memory()->virtual_membase(), obj_attributes_ptr + 4);
|
||||
if (!name.empty()) {
|
||||
X_HANDLE handle = X_INVALID_HANDLE_VALUE;
|
||||
X_RESULT result =
|
||||
kernel_state->object_table()->GetObjectByName(name, &handle);
|
||||
|
@ -477,7 +474,7 @@ SHIM_CALL NtCreateEvent_shim(PPCContext* ppc_context,
|
|||
|
||||
// obj_attributes may have a name inside of it, if != NULL.
|
||||
if (obj_attributes_ptr) {
|
||||
ev->SetAttributes(SHIM_MEM_ADDR(obj_attributes_ptr));
|
||||
ev->SetAttributes(obj_attributes_ptr);
|
||||
}
|
||||
|
||||
if (handle_ptr) {
|
||||
|
@ -641,7 +638,7 @@ SHIM_CALL NtCreateSemaphore_shim(PPCContext* ppc_context,
|
|||
|
||||
// obj_attributes may have a name inside of it, if != NULL.
|
||||
if (obj_attributes_ptr) {
|
||||
sem->SetAttributes(SHIM_MEM_ADDR(obj_attributes_ptr));
|
||||
sem->SetAttributes(obj_attributes_ptr);
|
||||
}
|
||||
|
||||
if (handle_ptr) {
|
||||
|
@ -738,7 +735,7 @@ SHIM_CALL NtCreateMutant_shim(PPCContext* ppc_context,
|
|||
|
||||
// obj_attributes may have a name inside of it, if != NULL.
|
||||
if (obj_attributes_ptr) {
|
||||
mutant->SetAttributes(SHIM_MEM_ADDR(obj_attributes_ptr));
|
||||
mutant->SetAttributes(obj_attributes_ptr);
|
||||
}
|
||||
|
||||
if (handle_ptr) {
|
||||
|
@ -800,7 +797,7 @@ SHIM_CALL NtCreateTimer_shim(PPCContext* ppc_context,
|
|||
|
||||
// obj_attributes may have a name inside of it, if != NULL.
|
||||
if (obj_attributes_ptr) {
|
||||
timer->SetAttributes(SHIM_MEM_ADDR(obj_attributes_ptr));
|
||||
timer->SetAttributes(obj_attributes_ptr);
|
||||
}
|
||||
|
||||
if (handle_ptr) {
|
||||
|
|
|
@ -88,15 +88,15 @@ X_STATUS XObject::Delete() {
|
|||
}
|
||||
}
|
||||
|
||||
void XObject::SetAttributes(const uint8_t* obj_attrs_ptr) {
|
||||
if (!obj_attrs_ptr) {
|
||||
void XObject::SetAttributes(uint32_t obj_attributes_ptr) {
|
||||
if (!obj_attributes_ptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t name_str_ptr = xe::load_and_swap<uint32_t>(obj_attrs_ptr + 4);
|
||||
if (name_str_ptr) {
|
||||
X_ANSI_STRING name_str(memory()->virtual_membase(), name_str_ptr);
|
||||
name_ = name_str.to_string();
|
||||
auto name = X_ANSI_STRING::to_string_indirect(memory()->virtual_membase(),
|
||||
obj_attributes_ptr + 4);
|
||||
if (!name.empty()) {
|
||||
name_ = std::move(name);
|
||||
kernel_state_->object_table()->AddNameMapping(name_, handle_);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -126,7 +126,7 @@ class XObject {
|
|||
// Reference()
|
||||
// Dereference()
|
||||
|
||||
void SetAttributes(const uint8_t* obj_attrs_ptr);
|
||||
void SetAttributes(uint32_t obj_attributes_ptr);
|
||||
|
||||
X_STATUS Wait(uint32_t wait_reason, uint32_t processor_mode,
|
||||
uint32_t alertable, uint64_t* opt_timeout);
|
||||
|
|
|
@ -139,6 +139,8 @@ typedef uint32_t X_HRESULT;
|
|||
#define X_INVALID_SOCKET (uint32_t)(~0)
|
||||
#define X_SOCKET_ERROR (uint32_t)(-1)
|
||||
|
||||
// clang-format on
|
||||
|
||||
enum X_FILE_ATTRIBUTES : uint32_t {
|
||||
X_FILE_ATTRIBUTE_NONE = 0x0000,
|
||||
X_FILE_ATTRIBUTE_READONLY = 0x0001,
|
||||
|
@ -235,45 +237,53 @@ inline void XOverlappedSetExtendedError(void* ptr, uint32_t value) {
|
|||
xe::store_and_swap<uint32_t>(&p[6], value);
|
||||
}
|
||||
|
||||
class X_ANSI_STRING {
|
||||
private:
|
||||
uint16_t length;
|
||||
uint16_t maximum_length;
|
||||
const char* buffer;
|
||||
struct X_ANSI_STRING {
|
||||
xe::be<uint16_t> length;
|
||||
xe::be<uint16_t> maximum_length;
|
||||
xe::be<uint32_t> pointer;
|
||||
|
||||
public:
|
||||
X_ANSI_STRING() { Zero(); }
|
||||
X_ANSI_STRING(const uint8_t* base, uint32_t p) { Read(base, p); }
|
||||
void Read(const uint8_t* base, uint32_t p) {
|
||||
length = xe::load_and_swap<uint16_t>(base + p);
|
||||
maximum_length = xe::load_and_swap<uint16_t>(base + p + 2);
|
||||
if (maximum_length) {
|
||||
buffer = (const char*)(base + xe::load_and_swap<uint32_t>(base + p + 4));
|
||||
} else {
|
||||
buffer = 0;
|
||||
}
|
||||
}
|
||||
void Zero() {
|
||||
length = maximum_length = 0;
|
||||
buffer = 0;
|
||||
}
|
||||
char* Duplicate() {
|
||||
if (!buffer || !length) {
|
||||
static X_ANSI_STRING* Translate(uint8_t* membase, uint32_t guest_address) {
|
||||
if (!guest_address) {
|
||||
return nullptr;
|
||||
}
|
||||
auto copy = (char*)calloc(length + 1, sizeof(char));
|
||||
std::strncpy(copy, buffer, length);
|
||||
return copy;
|
||||
return reinterpret_cast<X_ANSI_STRING*>(membase + guest_address);
|
||||
}
|
||||
std::string to_string() {
|
||||
if (!buffer || !length) {
|
||||
|
||||
static X_ANSI_STRING* TranslateIndirect(uint8_t* membase,
|
||||
uint32_t guest_address_ptr) {
|
||||
if (!guest_address_ptr) {
|
||||
return nullptr;
|
||||
}
|
||||
uint32_t guest_address =
|
||||
xe::load_and_swap<uint32_t>(membase + guest_address_ptr);
|
||||
return Translate(membase, guest_address);
|
||||
}
|
||||
|
||||
static std::string to_string(uint8_t* membase, uint32_t guest_address) {
|
||||
auto str = Translate(membase, guest_address);
|
||||
return str ? str->to_string(membase) : "";
|
||||
}
|
||||
|
||||
static std::string to_string_indirect(uint8_t* membase,
|
||||
uint32_t guest_address_ptr) {
|
||||
auto str = TranslateIndirect(membase, guest_address_ptr);
|
||||
return str ? str->to_string(membase) : "";
|
||||
}
|
||||
|
||||
void reset() {
|
||||
length = 0;
|
||||
maximum_length = 0;
|
||||
pointer = 0;
|
||||
}
|
||||
|
||||
std::string to_string(uint8_t* membase) const {
|
||||
if (!length) {
|
||||
return "";
|
||||
}
|
||||
std::string result(buffer, length);
|
||||
return result;
|
||||
return std::string(reinterpret_cast<const char*>(membase + pointer),
|
||||
length);
|
||||
}
|
||||
};
|
||||
// static_assert_size(X_ANSI_STRING, 8);
|
||||
|
||||
// http://pastebin.com/SMypYikG
|
||||
typedef uint32_t XNotificationID;
|
||||
|
|
Loading…
Reference in New Issue