Some NtQueryInformation classes.

This commit is contained in:
Ben Vanik 2013-10-16 22:19:50 -07:00
parent 956496fb99
commit a41827942e
11 changed files with 262 additions and 68 deletions

View File

@ -91,7 +91,7 @@ Entry* DiscImageDevice::ResolvePath(const char* path) {
XEIGNORE(xestrcpya(remaining, XECOUNT(remaining), next_slash + 1)); XEIGNORE(xestrcpya(remaining, XECOUNT(remaining), next_slash + 1));
} }
Entry::Type type = gdfx_entry->attributes & GDFXEntry::kAttrFolder ? Entry::Type type = gdfx_entry->attributes & X_FILE_ATTRIBUTE_DIRECTORY ?
Entry::kTypeDirectory : Entry::kTypeFile; Entry::kTypeDirectory : Entry::kTypeFile;
return new DiscImageEntry( return new DiscImageEntry(
type, this, path, mmap_, gdfx_entry); type, this, path, mmap_, gdfx_entry);

View File

@ -29,6 +29,19 @@ DiscImageFile::DiscImageFile(
DiscImageFile::~DiscImageFile() { DiscImageFile::~DiscImageFile() {
} }
X_STATUS DiscImageFile::QueryInfo(FileInfo* out_info) {
XEASSERTNOTNULL(out_info);
GDFXEntry* gdfx_entry = entry_->gdfx_entry();
out_info->creation_time = 0;
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->attributes = gdfx_entry->attributes;
return X_STATUS_SUCCESS;
}
X_STATUS DiscImageFile::ReadSync( X_STATUS DiscImageFile::ReadSync(
void* buffer, size_t buffer_length, size_t byte_offset, void* buffer, size_t buffer_length, size_t byte_offset,
size_t* out_bytes_read) { size_t* out_bytes_read) {

View File

@ -1,50 +1,51 @@
/** /**
****************************************************************************** ******************************************************************************
* Xenia : Xbox 360 Emulator Research Project * * Xenia : Xbox 360 Emulator Research Project *
****************************************************************************** ******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. * * Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. * * Released under the BSD license - see LICENSE in the root for more details. *
****************************************************************************** ******************************************************************************
*/ */
#ifndef XENIA_KERNEL_MODULES_XBOXKRNL_FS_DEVICES_DISC_IMAGE_FILE_H_ #ifndef XENIA_KERNEL_MODULES_XBOXKRNL_FS_DEVICES_DISC_IMAGE_FILE_H_
#define XENIA_KERNEL_MODULES_XBOXKRNL_FS_DEVICES_DISC_IMAGE_FILE_H_ #define XENIA_KERNEL_MODULES_XBOXKRNL_FS_DEVICES_DISC_IMAGE_FILE_H_
#include <xenia/common.h> #include <xenia/common.h>
#include <xenia/core.h> #include <xenia/core.h>
#include <xenia/kernel/modules/xboxkrnl/objects/xfile.h> #include <xenia/kernel/modules/xboxkrnl/objects/xfile.h>
namespace xe { namespace xe {
namespace kernel { namespace kernel {
namespace xboxkrnl { namespace xboxkrnl {
namespace fs { namespace fs {
class DiscImageEntry; class DiscImageEntry;
class DiscImageFile : public XFile { class DiscImageFile : public XFile {
public: public:
DiscImageFile(KernelState* kernel_state, uint32_t desired_access, DiscImageFile(KernelState* kernel_state, uint32_t desired_access,
DiscImageEntry* entry); DiscImageEntry* entry);
virtual ~DiscImageFile(); virtual ~DiscImageFile();
virtual X_STATUS QueryInfo(FileInfo* out_info);
protected:
protected:
virtual X_STATUS ReadSync( virtual X_STATUS ReadSync(
void* buffer, size_t buffer_length, size_t byte_offset, void* buffer, size_t buffer_length, size_t byte_offset,
size_t* out_bytes_read); size_t* out_bytes_read);
private: private:
DiscImageEntry* entry_; DiscImageEntry* entry_;
}; };
} // namespace fs } // namespace fs
} // namespace xboxkrnl } // namespace xboxkrnl
} // namespace kernel } // namespace kernel
} // namespace xe } // namespace xe
#endif // XENIA_KERNEL_MODULES_XBOXKRNL_FS_DEVICES_DISC_IMAGE_FILE_H_ #endif // XENIA_KERNEL_MODULES_XBOXKRNL_FS_DEVICES_DISC_IMAGE_FILE_H_

View File

@ -29,6 +29,26 @@ HostPathFile::~HostPathFile() {
CloseHandle(file_handle_); CloseHandle(file_handle_);
} }
X_STATUS HostPathFile::QueryInfo(FileInfo* out_info) {
XEASSERTNOTNULL(out_info);
WIN32_FILE_ATTRIBUTE_DATA data;
if (!GetFileAttributesEx(
entry_->local_path(), GetFileExInfoStandard, &data)) {
return X_STATUS_ACCESS_DENIED;
}
#define COMBINE_TIME(t) (((uint64_t)t.dwHighDateTime << 32) | t.dwLowDateTime)
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->attributes = (X_FILE_ATTRIBUTES)data.dwFileAttributes;
return X_STATUS_SUCCESS;
}
X_STATUS HostPathFile::ReadSync( X_STATUS HostPathFile::ReadSync(
void* buffer, size_t buffer_length, size_t byte_offset, void* buffer, size_t buffer_length, size_t byte_offset,
size_t* out_bytes_read) { size_t* out_bytes_read) {

View File

@ -30,6 +30,8 @@ public:
HostPathEntry* entry, HANDLE file_handle); HostPathEntry* entry, HANDLE file_handle);
virtual ~HostPathFile(); virtual ~HostPathFile();
virtual X_STATUS QueryInfo(FileInfo* out_info);
protected: protected:
virtual X_STATUS ReadSync( virtual X_STATUS ReadSync(
void* buffer, size_t buffer_length, size_t byte_offset, void* buffer, size_t buffer_length, size_t byte_offset,

View File

@ -25,7 +25,7 @@ namespace {
GDFXEntry::GDFXEntry() : GDFXEntry::GDFXEntry() :
attributes(0), offset(0), size(0) { attributes(X_FILE_ATTRIBUTE_NONE), offset(0), size(0) {
} }
GDFXEntry::~GDFXEntry() { GDFXEntry::~GDFXEntry() {
@ -144,7 +144,7 @@ GDFX::Error GDFX::ReadAllEntries(ParseState& state,
root_entry_->offset = 0; root_entry_->offset = 0;
root_entry_->size = 0; root_entry_->size = 0;
root_entry_->name = ""; root_entry_->name = "";
root_entry_->attributes = GDFXEntry::kAttrFolder; root_entry_->attributes = X_FILE_ATTRIBUTE_DIRECTORY;
if (!ReadEntry(state, root_buffer, 0, root_entry_)) { if (!ReadEntry(state, root_buffer, 0, root_entry_)) {
return kErrorOutOfMemory; return kErrorOutOfMemory;
@ -172,12 +172,12 @@ bool GDFX::ReadEntry(ParseState& state, const uint8_t* buffer,
GDFXEntry* entry = new GDFXEntry(); GDFXEntry* entry = new GDFXEntry();
entry->name = std::string(name, name_length); entry->name = std::string(name, name_length);
entry->name.append(1, '\0'); entry->name.append(1, '\0');
entry->attributes = attributes; entry->attributes = (X_FILE_ATTRIBUTES)attributes;
// Add to parent. // Add to parent.
parent->children.push_back(entry); parent->children.push_back(entry);
if (attributes & GDFXEntry::kAttrFolder) { if (attributes & X_FILE_ATTRIBUTE_DIRECTORY) {
// Folder. // Folder.
entry->offset = 0; entry->offset = 0;
entry->size = 0; entry->size = 0;

View File

@ -15,6 +15,7 @@
#include <vector> #include <vector>
#include <xenia/kernel/xbox.h>
#include <xenia/kernel/modules/xboxkrnl/fs/entry.h> #include <xenia/kernel/modules/xboxkrnl/fs/entry.h>
@ -29,16 +30,6 @@ class GDFX;
class GDFXEntry { class GDFXEntry {
public: public:
enum Attributes {
kAttrNone = 0x00000000,
kAttrReadOnly = 0x00000001,
kAttrHidden = 0x00000002,
kAttrSystem = 0x00000004,
kAttrFolder = 0x00000010,
kAttrArchived = 0x00000020,
kAttrNormal = 0x00000080,
};
GDFXEntry(); GDFXEntry();
~GDFXEntry(); ~GDFXEntry();
@ -46,10 +37,10 @@ public:
void Dump(int indent); void Dump(int indent);
std::string name; std::string name;
uint32_t attributes; X_FILE_ATTRIBUTES attributes;
size_t offset; size_t offset;
size_t size; size_t size;
std::vector<GDFXEntry*> children; std::vector<GDFXEntry*> children;
}; };

View File

@ -38,6 +38,12 @@ X_STATUS XFile::Wait(uint32_t wait_reason, uint32_t processor_mode,
wait_reason, processor_mode, alertable, opt_timeout); wait_reason, processor_mode, alertable, opt_timeout);
} }
X_STATUS XFile::QueryInfo(FileInfo* out_info) {
XEASSERTNOTNULL(out_info);
xe_zero_struct(out_info, sizeof(FileInfo));
return X_STATUS_NOT_IMPLEMENTED;
}
X_STATUS XFile::Read(void* buffer, size_t buffer_length, size_t byte_offset, X_STATUS XFile::Read(void* buffer, size_t buffer_length, size_t byte_offset,
size_t* out_bytes_read) { size_t* out_bytes_read) {
if (byte_offset == -1) { if (byte_offset == -1) {

View File

@ -28,9 +28,22 @@ public:
XFile(KernelState* kernel_state, uint32_t desired_access); XFile(KernelState* kernel_state, uint32_t desired_access);
virtual ~XFile(); virtual ~XFile();
size_t position() const { return position_; }
virtual X_STATUS Wait(uint32_t wait_reason, uint32_t processor_mode, virtual X_STATUS Wait(uint32_t wait_reason, uint32_t processor_mode,
uint32_t alertable, uint64_t* opt_timeout); uint32_t alertable, uint64_t* opt_timeout);
typedef struct {
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;
} FileInfo;
virtual X_STATUS QueryInfo(FileInfo* out_info);
X_STATUS Read(void* buffer, size_t buffer_length, size_t byte_offset, X_STATUS Read(void* buffer, size_t buffer_length, size_t byte_offset,
size_t* out_bytes_read); size_t* out_bytes_read);
X_STATUS Read(void* buffer, size_t buffer_length, size_t byte_offset, X_STATUS Read(void* buffer, size_t buffer_length, size_t byte_offset,

View File

@ -233,7 +233,79 @@ SHIM_CALL NtQueryInformationFile_shim(
length, length,
file_info_class); file_info_class);
SHIM_SET_RETURN(X_STATUS_NO_SUCH_FILE); X_STATUS result = X_STATUS_SUCCESS;
uint32_t info = 0;
// Grab file.
XFile* file = NULL;
result = state->object_table()->GetObject(
file_handle, (XObject**)&file);
if (XSUCCEEDED(result)) {
result = X_STATUS_SUCCESS;
switch (file_info_class) {
case XFilePositionInformation:
// struct FILE_POSITION_INFORMATION {
// LARGE_INTEGER CurrentByteOffset;
// };
XEASSERT(length == 8);
info = 8;
SHIM_SET_MEM_64(file_info_ptr, file->position());
break;
case XFileNetworkOpenInformation:
// struct FILE_NETWORK_OPEN_INFORMATION {
// LARGE_INTEGER CreationTime;
// LARGE_INTEGER LastAccessTime;
// LARGE_INTEGER LastWriteTime;
// LARGE_INTEGER ChangeTime;
// LARGE_INTEGER AllocationSize;
// LARGE_INTEGER EndOfFile;
// ULONG FileAttributes;
// ULONG Unknown;
// };
XEASSERT(length == 56);
XFile::FileInfo file_info;
result = file->QueryInfo(&file_info);
if (XSUCCEEDED(result)) {
info = 56;
SHIM_SET_MEM_64(file_info_ptr,
file_info.creation_time);
SHIM_SET_MEM_64(file_info_ptr + 8,
file_info.last_access_time);
SHIM_SET_MEM_64(file_info_ptr + 16,
file_info.last_write_time);
SHIM_SET_MEM_64(file_info_ptr + 24,
file_info.change_time);
SHIM_SET_MEM_64(file_info_ptr + 32,
file_info.allocation_size);
SHIM_SET_MEM_64(file_info_ptr + 40,
file_info.file_length);
SHIM_SET_MEM_32(file_info_ptr + 48,
file_info.attributes);
SHIM_SET_MEM_32(file_info_ptr + 52, 0); // Unknown!
}
break;
default:
// Unsupported, for now.
XEASSERTALWAYS();
info = 0;
break;
}
}
if (XFAILED(result)) {
info = 0;
}
if (io_status_block_ptr) {
SHIM_SET_MEM_32(io_status_block_ptr, result); // Status
SHIM_SET_MEM_32(io_status_block_ptr + 4, info); // Information
}
if (file) {
file->Release();
}
SHIM_SET_RETURN(result);
} }
SHIM_CALL NtQueryFullAttributesFile_shim( SHIM_CALL NtQueryFullAttributesFile_shim(

View File

@ -107,6 +107,82 @@ typedef uint32_t X_STATUS;
#define X_LANGUAGE_JAPANESE 2 #define X_LANGUAGE_JAPANESE 2
typedef enum _X_FILE_ATTRIBUTES {
X_FILE_ATTRIBUTE_NONE = 0x0000,
X_FILE_ATTRIBUTE_READONLY = 0x0001,
X_FILE_ATTRIBUTE_HIDDEN = 0x0002,
X_FILE_ATTRIBUTE_SYSTEM = 0x0004,
X_FILE_ATTRIBUTE_DIRECTORY = 0x0010,
X_FILE_ATTRIBUTE_ARCHIVE = 0x0020,
X_FILE_ATTRIBUTE_DEVICE = 0x0040,
X_FILE_ATTRIBUTE_NORMAL = 0x0080,
X_FILE_ATTRIBUTE_TEMPORARY = 0x0100,
X_FILE_ATTRIBUTE_COMPRESSED = 0x0800,
X_FILE_ATTRIBUTE_ENCRYPTED = 0x4000,
} X_FILE_ATTRIBUTES;
typedef enum _X_FILE_INFORMATION_CLASS {
XFileDirectoryInformation = 1,
XFileFullDirectoryInformation,
XFileBothDirectoryInformation,
XFileBasicInformation,
XFileStandardInformation,
XFileInternalInformation,
XFileEaInformation,
XFileAccessInformation,
XFileNameInformation,
XFileRenameInformation,
XFileLinkInformation,
XFileNamesInformation,
XFileDispositionInformation,
XFilePositionInformation,
XFileFullEaInformation,
XFileModeInformation,
XFileAlignmentInformation,
XFileAllInformation,
XFileAllocationInformation,
XFileEndOfFileInformation,
XFileAlternateNameInformation,
XFileStreamInformation,
XFilePipeInformation,
XFilePipeLocalInformation,
XFilePipeRemoteInformation,
XFileMailslotQueryInformation,
XFileMailslotSetInformation,
XFileCompressionInformation,
XFileObjectIdInformation,
XFileCompletionInformation,
XFileMoveClusterInformation,
XFileQuotaInformation,
XFileReparsePointInformation,
XFileNetworkOpenInformation,
XFileAttributeTagInformation,
XFileTrackingInformation,
XFileIdBothDirectoryInformation,
XFileIdFullDirectoryInformation,
XFileValidDataLengthInformation,
XFileShortNameInformation,
XFileIoCompletionNotificationInformation,
XFileIoStatusBlockRangeInformation,
XFileIoPriorityHintInformation,
XFileSfioReserveInformation,
XFileSfioVolumeInformation,
XFileHardLinkInformation,
XFileProcessIdsUsingFileInformation,
XFileNormalizedNameInformation,
XFileNetworkPhysicalNameInformation,
XFileIdGlobalTxDirectoryInformation,
XFileIsRemoteDeviceInformation,
XFileAttributeCacheInformation,
XFileNumaNodeInformation,
XFileStandardLinkInformation,
XFileRemoteProtocolInformation,
XFileReplaceCompletionInformation,
XFileMaximumInformation
} X_FILE_INFORMATION_CLASS;
class X_ANSI_STRING { class X_ANSI_STRING {
public: public:
uint16_t length; uint16_t length;