NtQueryDirectoryFile and necessary backing. Not fully functional yet.

This commit is contained in:
gibbed
2014-01-18 05:59:22 -08:00
parent c257ad0122
commit 619b9758a0
9 changed files with 206 additions and 2 deletions

View File

@@ -32,6 +32,11 @@ X_STATUS DiscImageFile::QueryInfo(XFileInfo* out_info) {
return entry_->QueryInfo(out_info);
}
X_STATUS DiscImageFile::QueryDirectory(XDirectoryInfo* out_info, size_t length, bool restart) {
XEASSERTALWAYS();
return X_STATUS_SUCCESS;
}
X_STATUS DiscImageFile::ReadSync(
void* buffer, size_t buffer_length, size_t byte_offset,
size_t* out_bytes_read) {

View File

@@ -30,6 +30,7 @@ public:
virtual ~DiscImageFile();
virtual X_STATUS QueryInfo(XFileInfo* out_info);
virtual X_STATUS QueryDirectory(XDirectoryInfo* out_info, size_t length, bool restart);
protected:
virtual X_STATUS ReadSync(

View File

@@ -39,14 +39,20 @@ private:
HostPathEntry::HostPathEntry(Type type, Device* device, const char* path,
const xechar_t* local_path) :
Entry(type, device, path) {
Entry(type, device, path),
find_file_(INVALID_HANDLE_VALUE) {
local_path_ = xestrdup(local_path);
}
HostPathEntry::~HostPathEntry() {
if (find_file_ != INVALID_HANDLE_VALUE) {
FindClose(find_file_);
}
xe_free(local_path_);
}
#define COMBINE_TIME(t) (((uint64_t)t.dwHighDateTime << 32) | t.dwLowDateTime)
X_STATUS HostPathEntry::QueryInfo(XFileInfo* out_info) {
XEASSERTNOTNULL(out_info);
@@ -56,7 +62,6 @@ X_STATUS HostPathEntry::QueryInfo(XFileInfo* out_info) {
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);
@@ -67,6 +72,86 @@ X_STATUS HostPathEntry::QueryInfo(XFileInfo* out_info) {
return X_STATUS_SUCCESS;
}
X_STATUS HostPathEntry::QueryDirectory(XDirectoryInfo* out_info, size_t length, bool restart) {
XEASSERTNOTNULL(out_info);
if (length < sizeof(XDirectoryInfo)) {
return X_STATUS_INFO_LENGTH_MISMATCH;
}
memset(out_info, 0, length);
WIN32_FIND_DATA ffd;
HANDLE handle = find_file_;
if (restart == true && handle != INVALID_HANDLE_VALUE) {
FindClose(find_file_);
handle = find_file_ = INVALID_HANDLE_VALUE;
}
if (handle == INVALID_HANDLE_VALUE) {
handle = find_file_ = FindFirstFile(local_path_, &ffd);
if (handle == INVALID_HANDLE_VALUE) {
if (GetLastError() == ERROR_FILE_NOT_FOUND) {
return X_STATUS_NO_SUCH_FILE;
}
return X_STATUS_UNSUCCESSFUL;
}
}
else {
if (FindNextFile(handle, &ffd) == FALSE) {
FindClose(handle);
find_file_ = INVALID_HANDLE_VALUE;
return X_STATUS_UNSUCCESSFUL;
}
}
XDirectoryInfo* current;
auto current_buf = (uint8_t*)out_info;
auto end = current_buf + length;
current = (XDirectoryInfo*)current_buf;
if (((uint8_t*)&current->file_name[0]) + wcslen(ffd.cFileName) > end) {
FindClose(handle);
find_file_ = INVALID_HANDLE_VALUE;
return X_STATUS_UNSUCCESSFUL;
}
do
{
size_t file_name_length = wcslen(ffd.cFileName);
if (((uint8_t*)&((XDirectoryInfo*)current_buf)->file_name[0]) + wcslen(ffd.cFileName) > end) {
break;
}
current = (XDirectoryInfo*)current_buf;
current->file_index = 0xCDCDCDCD;
current->creation_time = COMBINE_TIME(ffd.ftCreationTime);
current->last_access_time = COMBINE_TIME(ffd.ftLastAccessTime);
current->last_write_time = COMBINE_TIME(ffd.ftLastWriteTime);
current->change_time = COMBINE_TIME(ffd.ftLastWriteTime);
current->end_of_file = ((uint64_t)ffd.nFileSizeHigh << 32) | ffd.nFileSizeLow;
current->allocation_size = 4096;
current->attributes = (X_FILE_ATTRIBUTES)ffd.dwFileAttributes;
// TODO: I am pretty sure you need to prefix the file paths with full path, not just the name.
current->file_name_length = (uint32_t)file_name_length;
for (size_t i = 0; i < file_name_length; ++i) {
current->file_name[i] = ffd.cFileName[i] < 256 ? (char)ffd.cFileName[i] : '?';
}
auto next_buf = (((uint8_t*)&current->file_name[0]) + file_name_length);
next_buf += 8 - ((uint8_t)next_buf % 8);
current->next_entry_offset = (uint32_t)(next_buf - current_buf);
current_buf = next_buf;
} while (current_buf < end && FindNextFile(handle, &ffd) == TRUE);
current->next_entry_offset = 0;
return X_STATUS_SUCCESS;
}
MemoryMapping* HostPathEntry::CreateMemoryMapping(
xe_file_mode file_mode, const size_t offset, const size_t length) {
xe_mmap_ref mmap = xe_mmap_open(file_mode, local_path_, offset, length);

View File

@@ -30,6 +30,7 @@ public:
const xechar_t* local_path() { return local_path_; }
virtual X_STATUS QueryInfo(XFileInfo* out_info);
virtual X_STATUS QueryDirectory(XDirectoryInfo* out_info, size_t length, bool restart);
virtual MemoryMapping* CreateMemoryMapping(
xe_file_mode file_mode, const size_t offset, const size_t length);
@@ -41,6 +42,7 @@ public:
private:
xechar_t* local_path_;
HANDLE find_file_;
};

View File

@@ -32,6 +32,10 @@ X_STATUS HostPathFile::QueryInfo(XFileInfo* out_info) {
return entry_->QueryInfo(out_info);
}
X_STATUS HostPathFile::QueryDirectory(XDirectoryInfo* out_info, size_t length, bool restart) {
return entry_->QueryDirectory(out_info, length, restart);
}
X_STATUS HostPathFile::ReadSync(
void* buffer, size_t buffer_length, size_t byte_offset,
size_t* out_bytes_read) {

View File

@@ -30,6 +30,7 @@ public:
virtual ~HostPathFile();
virtual X_STATUS QueryInfo(XFileInfo* out_info);
virtual X_STATUS QueryDirectory(XDirectoryInfo* out_info, size_t length, bool restart);
protected:
virtual X_STATUS ReadSync(

View File

@@ -19,6 +19,7 @@
XEDECLARECLASS2(xe, kernel, KernelState);
XEDECLARECLASS2(xe, kernel, XFile);
XEDECLARECLASS2(xe, kernel, XFileInfo);
XEDECLARECLASS2(xe, kernel, XDirectoryInfo);
namespace xe {