Replacing X_ANSI_STRING with new style.

Progress on #297.
This commit is contained in:
Ben Vanik 2015-06-27 12:16:52 -07:00
parent f07d620553
commit c2e2b3380e
6 changed files with 104 additions and 64 deletions

View File

@ -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);
}

View File

@ -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);

View File

@ -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) {

View File

@ -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_);
}
}

View File

@ -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);

View File

@ -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;