Turns out NtQueryDirectoryFile only returns a single entry at a time.

This commit is contained in:
gibbed
2014-01-19 06:56:56 -08:00
parent c7276454d7
commit 870a59f225
5 changed files with 126 additions and 138 deletions

View File

@@ -84,45 +84,29 @@ X_STATUS DiscImageEntry::QueryDirectory(
}
}
auto current_buf = (uint8_t*)out_info;
auto end = current_buf + length;
auto end = (uint8_t*)out_info + length;
XDirectoryInfo* current = (XDirectoryInfo*)current_buf;
if (((uint8_t*)&current->file_name[0]) + xestrlena((*gdfx_entry_iterator_)->name.c_str()) > end) {
auto entry = *gdfx_entry_iterator_;
auto entry_name = entry->name.c_str();
size_t entry_name_length = xestrlena(entry_name);
if (((uint8_t*)&out_info->file_name[0]) + entry_name_length > end) {
gdfx_entry_iterator_ = gdfx_entry_->children.end();
return X_STATUS_UNSUCCESSFUL;
}
do {
auto entry = *gdfx_entry_iterator_;
out_info->next_entry_offset = 0;
out_info->file_index = 0xCDCDCDCD;
out_info->creation_time = 0;
out_info->last_access_time = 0;
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->attributes = (X_FILE_ATTRIBUTES)entry->attributes;
out_info->file_name_length = (uint32_t)entry_name_length;
memcpy(out_info->file_name, entry_name, entry_name_length);
auto file_name = entry->name.c_str();
size_t file_name_length = xestrlena(file_name);
if (((uint8_t*)&((XDirectoryInfo*)current_buf)->file_name[0]) + file_name_length > end) {
break;
}
current = (XDirectoryInfo*)current_buf;
current->file_index = 0xCDCDCDCD;
current->creation_time = 0;
current->last_access_time = 0;
current->last_write_time = 0;
current->change_time = 0;
current->end_of_file = entry->size;
current->allocation_size = 2048;
current->attributes = (X_FILE_ATTRIBUTES)entry->attributes;
current->file_name_length = (uint32_t)file_name_length;
memcpy(current->file_name, file_name, file_name_length);
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 &&
(++gdfx_entry_iterator_) != gdfx_entry_->children.end());
current->next_entry_offset = 0;
return X_STATUS_SUCCESS;
}

View File

@@ -87,10 +87,19 @@ X_STATUS HostPathEntry::QueryDirectory(
}
if (handle == INVALID_HANDLE_VALUE) {
handle = find_file_ = FindFirstFile(local_path_, &ffd);
xechar_t target_path[XE_MAX_PATH];
xestrcpy(target_path, XE_MAX_PATH, local_path_);
if (file_name == NULL) {
xestrcat(target_path, XE_MAX_PATH, XETEXT("*"));
}
else {
auto target_length = xestrlen(local_path_);
xestrwiden(target_path + target_length, XECOUNT(target_path) - target_length, file_name);
}
handle = find_file_ = FindFirstFile(target_path, &ffd);
if (handle == INVALID_HANDLE_VALUE) {
if (GetLastError() == ERROR_FILE_NOT_FOUND) {
return X_STATUS_NO_SUCH_FILE;
return X_STATUS_NO_MORE_FILES;
}
return X_STATUS_UNSUCCESSFUL;
}
@@ -99,53 +108,35 @@ X_STATUS HostPathEntry::QueryDirectory(
if (FindNextFile(handle, &ffd) == FALSE) {
FindClose(handle);
find_file_ = INVALID_HANDLE_VALUE;
return X_STATUS_UNSUCCESSFUL;
return X_STATUS_NO_MORE_FILES;
}
}
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) {
auto end = (uint8_t*)out_info + length;
size_t entry_name_length = wcslen(ffd.cFileName);
if (((uint8_t*)&out_info->file_name[0]) + entry_name_length > end) {
FindClose(handle);
find_file_ = INVALID_HANDLE_VALUE;
return X_STATUS_UNSUCCESSFUL;
return X_STATUS_BUFFER_OVERFLOW;
}
do {
size_t file_name_length = wcslen(ffd.cFileName);
if (((uint8_t*)&((XDirectoryInfo*)current_buf)->file_name[0]) +
file_name_length > end) {
break;
}
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->attributes = (X_FILE_ATTRIBUTES)ffd.dwFileAttributes;
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;
out_info->file_name_length = (uint32_t)entry_name_length;
for (size_t i = 0; i < entry_name_length; ++i) {
out_info->file_name[i] =
ffd.cFileName[i] < 256 ? (char)ffd.cFileName[i] : '?';
}
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;
}
@@ -177,9 +168,9 @@ X_STATUS HostPathEntry::Open(
share_mode,
NULL,
creation_disposition,
flags_and_attributes,
flags_and_attributes | FILE_FLAG_BACKUP_SEMANTICS,
NULL);
if (!file) {
if (file == INVALID_HANDLE_VALUE) {
// TODO(benvanik): pick correct response.
return X_STATUS_ACCESS_DENIED;
}

View File

@@ -63,45 +63,28 @@ X_STATUS STFSContainerEntry::QueryDirectory(
}
}
auto current_buf = (uint8_t*)out_info;
auto end = current_buf + length;
auto end = (uint8_t*)out_info + length;
XDirectoryInfo* current = (XDirectoryInfo*)current_buf;
if (((uint8_t*)&current->file_name[0]) + xestrlena((*stfs_entry_iterator_)->name.c_str()) > end) {
auto entry = *stfs_entry_iterator_;
auto entry_name = entry->name.c_str();
size_t entry_name_length = xestrlena(entry_name);
if (((uint8_t*)&out_info->file_name[0]) + entry_name_length > end) {
stfs_entry_iterator_ = stfs_entry_->children.end();
return X_STATUS_UNSUCCESSFUL;
}
do {
auto entry = *stfs_entry_iterator_;
out_info->file_index = 0xCDCDCDCD;
out_info->creation_time = entry->update_timestamp;
out_info->last_access_time = entry->access_timestamp;
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->attributes = entry->attributes;
out_info->file_name_length = (uint32_t)entry_name_length;
memcpy(out_info->file_name, entry_name, entry_name_length);
auto file_name = entry->name.c_str();
size_t file_name_length = xestrlena(file_name);
if (((uint8_t*)&((XDirectoryInfo*)current_buf)->file_name[0]) + file_name_length > end) {
break;
}
current = (XDirectoryInfo*)current_buf;
current->file_index = 0xCDCDCDCD;
current->creation_time = entry->update_timestamp;
current->last_access_time = entry->access_timestamp;
current->last_write_time = entry->update_timestamp;
current->change_time = entry->update_timestamp;
current->end_of_file = entry->size;
current->allocation_size = 4096;
current->attributes = entry->attributes;
current->file_name_length = (uint32_t)file_name_length;
memcpy(current->file_name, file_name, file_name_length);
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 &&
(++stfs_entry_iterator_) != stfs_entry_->children.end());
current->next_entry_offset = 0;
return X_STATUS_SUCCESS;
}