Fixing end_of_file and allocation_size, some wildcard stuff, etc.

This commit is contained in:
Ben Vanik 2015-06-02 22:09:32 -07:00
parent 25a2fbd78e
commit e186fcaf0d
10 changed files with 68 additions and 67 deletions

View File

@ -68,6 +68,14 @@ inline double byte_swap(double value) {
uint64_t temp = byte_swap(*reinterpret_cast<uint64_t *>(&value));
return *reinterpret_cast<double *>(&temp);
}
template <typename T>
inline T byte_swap(T value) {
if (sizeof(T) == 4) {
return static_cast<T>(byte_swap(static_cast<uint32_t>(value)));
} else {
assert_always("not handled");
}
}
template <typename T>
struct be {

View File

@ -11,6 +11,7 @@
#include <algorithm>
#include "xenia/base/math.h"
#include "xenia/kernel/fs/devices/disc_image_file.h"
namespace xe {
@ -30,7 +31,7 @@ DiscImageEntry::DiscImageEntry(Device* device, const char* path,
: Entry(device, path),
mmap_(mmap),
gdfx_entry_(gdfx_entry),
it_(gdfx_entry->children.end()) {}
it_(gdfx_entry->children.begin()) {}
DiscImageEntry::~DiscImageEntry() {}
@ -40,8 +41,8 @@ X_STATUS DiscImageEntry::QueryInfo(X_FILE_NETWORK_OPEN_INFORMATION* out_info) {
out_info->last_access_time = 0;
out_info->last_write_time = 0;
out_info->change_time = 0;
out_info->allocation_size = 2048;
out_info->file_length = gdfx_entry_->size;
out_info->allocation_size = xe::round_up(gdfx_entry_->size, 2048);
out_info->end_of_file = gdfx_entry_->size;
out_info->attributes = gdfx_entry_->attributes;
return X_STATUS_SUCCESS;
}
@ -71,13 +72,13 @@ X_STATUS DiscImageEntry::QueryDirectory(X_FILE_DIRECTORY_INFORMATION* out_info,
entry = gdfx_entry_->GetChild(find_engine_, it_);
if (!entry) {
return X_STATUS_UNSUCCESSFUL;
return X_STATUS_NO_SUCH_FILE;
}
auto end = (uint8_t*)out_info + length;
auto entry_name = entry->name;
if (((uint8_t*)&out_info->file_name[0]) + entry_name.size() > end) {
return X_STATUS_NO_MORE_FILES;
return X_STATUS_NO_SUCH_FILE;
}
}
@ -88,7 +89,7 @@ X_STATUS DiscImageEntry::QueryDirectory(X_FILE_DIRECTORY_INFORMATION* out_info,
out_info->last_write_time = 0;
out_info->change_time = 0;
out_info->end_of_file = entry->size;
out_info->allocation_size = 2048;
out_info->allocation_size = xe::round_up(entry->size, 2048);
out_info->attributes = entry->attributes;
out_info->file_name_length = static_cast<uint32_t>(entry->name.size());
memcpy(out_info->file_name, entry->name.c_str(), entry->name.size());

View File

@ -48,7 +48,7 @@ X_STATUS DiscImageFile::ReadSync(void* buffer, size_t buffer_length,
}
size_t real_offset = gdfx_entry->offset + byte_offset;
size_t real_length = std::min(buffer_length, gdfx_entry->size - byte_offset);
memcpy(buffer, entry_->mmap()->data() + real_offset, real_length);
std::memcpy(buffer, entry_->mmap()->data() + real_offset, real_length);
*out_bytes_read = real_length;
return X_STATUS_SUCCESS;
}

View File

@ -10,6 +10,7 @@
#include "xenia/kernel/fs/devices/host_path_entry.h"
#include "xenia/base/mapped_memory.h"
#include "xenia/base/math.h"
#include "xenia/base/string.h"
#include "xenia/kernel/fs/devices/host_path_file.h"
@ -48,13 +49,14 @@ X_STATUS HostPathEntry::QueryInfo(X_FILE_NETWORK_OPEN_INFORMATION* out_info) {
return X_STATUS_ACCESS_DENIED;
}
uint64_t file_size = ((uint64_t)data.nFileSizeHigh << 32) | data.nFileSizeLow;
out_info->creation_time = COMBINE_TIME(data.ftCreationTime);
out_info->last_access_time = COMBINE_TIME(data.ftLastAccessTime);
out_info->last_write_time = COMBINE_TIME(data.ftLastWriteTime);
out_info->change_time = COMBINE_TIME(data.ftLastWriteTime);
out_info->allocation_size = 4096;
out_info->file_length =
((uint64_t)data.nFileSizeHigh << 32) | data.nFileSizeLow;
out_info->allocation_size = xe::round_up(file_size, 4096);
out_info->end_of_file = file_size;
out_info->attributes = (X_FILE_ATTRIBUTES)data.dwFileAttributes;
return X_STATUS_SUCCESS;
}
@ -90,7 +92,7 @@ X_STATUS HostPathEntry::QueryDirectory(X_FILE_DIRECTORY_INFORMATION* out_info, s
if (FindNextFile(handle, &ffd) == FALSE) {
FindClose(handle);
find_file_ = INVALID_HANDLE_VALUE;
return X_STATUS_NO_MORE_FILES;
return X_STATUS_NO_SUCH_FILE;
}
}
@ -102,15 +104,16 @@ X_STATUS HostPathEntry::QueryDirectory(X_FILE_DIRECTORY_INFORMATION* out_info, s
return X_STATUS_BUFFER_OVERFLOW;
}
uint64_t file_size = ((uint64_t)ffd.nFileSizeHigh << 32) | ffd.nFileSizeLow;
out_info->next_entry_offset = 0;
out_info->file_index = 0xCDCDCDCD;
out_info->creation_time = COMBINE_TIME(ffd.ftCreationTime);
out_info->last_access_time = COMBINE_TIME(ffd.ftLastAccessTime);
out_info->last_write_time = COMBINE_TIME(ffd.ftLastWriteTime);
out_info->change_time = COMBINE_TIME(ffd.ftLastWriteTime);
out_info->end_of_file =
((uint64_t)ffd.nFileSizeHigh << 32) | ffd.nFileSizeLow;
out_info->allocation_size = 4096;
out_info->end_of_file = file_size;
out_info->allocation_size = xe::round_up(file_size, 4096);
out_info->attributes = (X_FILE_ATTRIBUTES)ffd.dwFileAttributes;
out_info->file_name_length = (uint32_t)entry_name_length;

View File

@ -9,6 +9,7 @@
#include "xenia/kernel/fs/devices/stfs_container_entry.h"
#include "xenia/base/math.h"
#include "xenia/kernel/fs/devices/stfs_container_file.h"
namespace xe {
@ -21,7 +22,7 @@ STFSContainerEntry::STFSContainerEntry(Device* device, const char* path,
: Entry(device, path),
mmap_(mmap),
stfs_entry_(stfs_entry),
it_(stfs_entry_->children.end()) {}
it_(stfs_entry_->children.begin()) {}
STFSContainerEntry::~STFSContainerEntry() = default;
@ -31,8 +32,8 @@ X_STATUS STFSContainerEntry::QueryInfo(X_FILE_NETWORK_OPEN_INFORMATION* out_info
out_info->last_access_time = stfs_entry_->access_timestamp;
out_info->last_write_time = stfs_entry_->update_timestamp;
out_info->change_time = stfs_entry_->update_timestamp;
out_info->allocation_size = 4096;
out_info->file_length = stfs_entry_->size;
out_info->allocation_size = xe::round_up(stfs_entry_->size, 4096);
out_info->end_of_file = stfs_entry_->size;
out_info->attributes = stfs_entry_->attributes;
return X_STATUS_SUCCESS;
}
@ -64,13 +65,13 @@ X_STATUS STFSContainerEntry::QueryDirectory(X_FILE_DIRECTORY_INFORMATION* out_in
entry = stfs_entry_->GetChild(find_engine_, it_);
if (!entry) {
return X_STATUS_UNSUCCESSFUL;
return X_STATUS_NO_SUCH_FILE;
}
auto end = (uint8_t*)out_info + length;
auto entry_name = entry->name;
if (((uint8_t*)&out_info->file_name[0]) + entry_name.size() > end) {
return X_STATUS_NO_MORE_FILES;
return X_STATUS_NO_SUCH_FILE;
}
}
@ -80,7 +81,7 @@ X_STATUS STFSContainerEntry::QueryDirectory(X_FILE_DIRECTORY_INFORMATION* out_in
out_info->last_write_time = entry->update_timestamp;
out_info->change_time = entry->update_timestamp;
out_info->end_of_file = entry->size;
out_info->allocation_size = 4096;
out_info->allocation_size = xe::round_up(entry->size, 4096);
out_info->attributes = entry->attributes;
out_info->file_name_length = static_cast<uint32_t>(entry->name.size());
memcpy(out_info->file_name, entry->name.c_str(), entry->name.size());

View File

@ -19,7 +19,7 @@ namespace xe {
namespace kernel {
class KernelState;
class XFile;
class X_FILE_NETWORK_OPEN_INFORMATION;
struct X_FILE_NETWORK_OPEN_INFORMATION;
class X_FILE_DIRECTORY_INFORMATION;
class X_FILE_FS_ATTRIBUTE_INFORMATION;
class X_FILE_FS_SIZE_INFORMATION;

View File

@ -22,27 +22,15 @@ class XAsyncRequest;
class XEvent;
// https://msdn.microsoft.com/en-us/library/windows/hardware/ff545822.aspx
class X_FILE_NETWORK_OPEN_INFORMATION {
public:
// FILE_NETWORK_OPEN_INFORMATION
uint64_t creation_time;
uint64_t last_access_time;
uint64_t last_write_time;
uint64_t change_time;
uint64_t allocation_size;
uint64_t file_length;
X_FILE_ATTRIBUTES attributes;
void Write(uint8_t* base, uint32_t p) {
xe::store_and_swap<uint64_t>(base + p, creation_time);
xe::store_and_swap<uint64_t>(base + p + 8, last_access_time);
xe::store_and_swap<uint64_t>(base + p + 16, last_write_time);
xe::store_and_swap<uint64_t>(base + p + 24, change_time);
xe::store_and_swap<uint64_t>(base + p + 32, allocation_size);
xe::store_and_swap<uint64_t>(base + p + 40, file_length);
xe::store_and_swap<uint32_t>(base + p + 48, attributes);
xe::store_and_swap<uint32_t>(base + p + 52, 0); // pad
}
struct X_FILE_NETWORK_OPEN_INFORMATION {
xe::be<uint64_t> creation_time;
xe::be<uint64_t> last_access_time;
xe::be<uint64_t> last_write_time;
xe::be<uint64_t> change_time;
xe::be<uint64_t> allocation_size;
xe::be<uint64_t> end_of_file; // size in bytes
xe::be<X_FILE_ATTRIBUTES> attributes;
xe::be<uint32_t> pad;
};
// https://msdn.microsoft.com/en-us/library/windows/hardware/ff540248.aspx
@ -55,7 +43,7 @@ class X_FILE_DIRECTORY_INFORMATION {
uint64_t last_access_time;
uint64_t last_write_time;
uint64_t change_time;
uint64_t end_of_file;
uint64_t end_of_file; // size in bytes
uint64_t allocation_size;
X_FILE_ATTRIBUTES attributes;
uint32_t file_name_length;

View File

@ -56,13 +56,13 @@ X_STATUS XUserModule::LoadFromFile(std::string path) {
// Load the module.
result = LoadFromMemory(mmap->address(), mmap->length());
} else {
X_FILE_NETWORK_OPEN_INFORMATION file_info;
X_FILE_NETWORK_OPEN_INFORMATION file_info = {0};
result = fs_entry->QueryInfo(&file_info);
if (result) {
return result;
}
std::vector<uint8_t> buffer(file_info.file_length);
std::vector<uint8_t> buffer(file_info.end_of_file);
// Open file for reading.
XFile* file_ptr = nullptr;

View File

@ -492,7 +492,7 @@ SHIM_CALL NtQueryInformationFile_shim(PPCContext* ppc_context,
info = 8;
SHIM_SET_MEM_64(file_info_ptr, file->position());
break;
case XFileNetworkOpenInformation:
case XFileNetworkOpenInformation: {
// struct FILE_NETWORK_OPEN_INFORMATION {
// LARGE_INTEGER CreationTime;
// LARGE_INTEGER LastAccessTime;
@ -504,13 +504,15 @@ SHIM_CALL NtQueryInformationFile_shim(PPCContext* ppc_context,
// ULONG Unknown;
// };
assert_true(length == 56);
X_FILE_NETWORK_OPEN_INFORMATION file_info;
result = file->QueryInfo(&file_info);
auto file_info =
kernel_memory()->TranslateVirtual<X_FILE_NETWORK_OPEN_INFORMATION*>(
file_info_ptr);
result = file->QueryInfo(file_info);
if (XSUCCEEDED(result)) {
info = 56;
file_info.Write(SHIM_MEM_BASE, file_info_ptr);
}
break;
}
case XFileXctdCompressionInformation:
assert_true(length == 4);
/*
@ -578,11 +580,10 @@ SHIM_CALL NtQueryFullAttributesFile_shim(PPCContext* ppc_context,
auto entry = fs->ResolvePath(object_name);
if (entry) {
// Found.
X_FILE_NETWORK_OPEN_INFORMATION file_info;
result = entry->QueryInfo(&file_info);
if (XSUCCEEDED(result)) {
file_info.Write(SHIM_MEM_BASE, file_info_ptr);
}
auto file_info =
kernel_memory()->TranslateVirtual<X_FILE_NETWORK_OPEN_INFORMATION*>(
file_info_ptr);
result = entry->QueryInfo(file_info);
}
free(object_name);

View File

@ -156,8 +156,7 @@ typedef uint32_t X_HRESULT;
#define X_LANGUAGE_ENGLISH 1
#define X_LANGUAGE_JAPANESE 2
enum X_FILE_ATTRIBUTES {
enum X_FILE_ATTRIBUTES : uint32_t {
X_FILE_ATTRIBUTE_NONE = 0x0000,
X_FILE_ATTRIBUTE_READONLY = 0x0001,
X_FILE_ATTRIBUTE_HIDDEN = 0x0002,