Turns out NtQueryDirectoryFile only returns a single entry at a time.
This commit is contained in:
parent
c7276454d7
commit
870a59f225
|
@ -84,45 +84,29 @@ X_STATUS DiscImageEntry::QueryDirectory(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto current_buf = (uint8_t*)out_info;
|
auto end = (uint8_t*)out_info + length;
|
||||||
auto end = current_buf + length;
|
|
||||||
|
|
||||||
XDirectoryInfo* current = (XDirectoryInfo*)current_buf;
|
auto entry = *gdfx_entry_iterator_;
|
||||||
if (((uint8_t*)¤t->file_name[0]) + xestrlena((*gdfx_entry_iterator_)->name.c_str()) > end) {
|
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();
|
gdfx_entry_iterator_ = gdfx_entry_->children.end();
|
||||||
return X_STATUS_UNSUCCESSFUL;
|
return X_STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
out_info->next_entry_offset = 0;
|
||||||
auto entry = *gdfx_entry_iterator_;
|
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*)¤t->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;
|
return X_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -87,10 +87,19 @@ X_STATUS HostPathEntry::QueryDirectory(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handle == INVALID_HANDLE_VALUE) {
|
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 (handle == INVALID_HANDLE_VALUE) {
|
||||||
if (GetLastError() == ERROR_FILE_NOT_FOUND) {
|
if (GetLastError() == ERROR_FILE_NOT_FOUND) {
|
||||||
return X_STATUS_NO_SUCH_FILE;
|
return X_STATUS_NO_MORE_FILES;
|
||||||
}
|
}
|
||||||
return X_STATUS_UNSUCCESSFUL;
|
return X_STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
@ -99,53 +108,35 @@ X_STATUS HostPathEntry::QueryDirectory(
|
||||||
if (FindNextFile(handle, &ffd) == FALSE) {
|
if (FindNextFile(handle, &ffd) == FALSE) {
|
||||||
FindClose(handle);
|
FindClose(handle);
|
||||||
find_file_ = INVALID_HANDLE_VALUE;
|
find_file_ = INVALID_HANDLE_VALUE;
|
||||||
return X_STATUS_UNSUCCESSFUL;
|
return X_STATUS_NO_MORE_FILES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
XDirectoryInfo* current;
|
auto end = (uint8_t*)out_info + length;
|
||||||
|
size_t entry_name_length = wcslen(ffd.cFileName);
|
||||||
auto current_buf = (uint8_t*)out_info;
|
if (((uint8_t*)&out_info->file_name[0]) + entry_name_length > end) {
|
||||||
auto end = current_buf + length;
|
|
||||||
|
|
||||||
current = (XDirectoryInfo*)current_buf;
|
|
||||||
if (((uint8_t*)¤t->file_name[0]) + wcslen(ffd.cFileName) > end) {
|
|
||||||
FindClose(handle);
|
FindClose(handle);
|
||||||
find_file_ = INVALID_HANDLE_VALUE;
|
find_file_ = INVALID_HANDLE_VALUE;
|
||||||
return X_STATUS_UNSUCCESSFUL;
|
return X_STATUS_BUFFER_OVERFLOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
out_info->next_entry_offset = 0;
|
||||||
size_t file_name_length = wcslen(ffd.cFileName);
|
out_info->file_index = 0xCDCDCDCD;
|
||||||
if (((uint8_t*)&((XDirectoryInfo*)current_buf)->file_name[0]) +
|
out_info->creation_time = COMBINE_TIME(ffd.ftCreationTime);
|
||||||
file_name_length > end) {
|
out_info->last_access_time = COMBINE_TIME(ffd.ftLastAccessTime);
|
||||||
break;
|
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;
|
out_info->file_name_length = (uint32_t)entry_name_length;
|
||||||
current->file_index = 0xCDCDCDCD;
|
for (size_t i = 0; i < entry_name_length; ++i) {
|
||||||
current->creation_time = COMBINE_TIME(ffd.ftCreationTime);
|
out_info->file_name[i] =
|
||||||
current->last_access_time = COMBINE_TIME(ffd.ftLastAccessTime);
|
ffd.cFileName[i] < 256 ? (char)ffd.cFileName[i] : '?';
|
||||||
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;
|
|
||||||
|
|
||||||
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*)¤t->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;
|
return X_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,9 +168,9 @@ X_STATUS HostPathEntry::Open(
|
||||||
share_mode,
|
share_mode,
|
||||||
NULL,
|
NULL,
|
||||||
creation_disposition,
|
creation_disposition,
|
||||||
flags_and_attributes,
|
flags_and_attributes | FILE_FLAG_BACKUP_SEMANTICS,
|
||||||
NULL);
|
NULL);
|
||||||
if (!file) {
|
if (file == INVALID_HANDLE_VALUE) {
|
||||||
// TODO(benvanik): pick correct response.
|
// TODO(benvanik): pick correct response.
|
||||||
return X_STATUS_ACCESS_DENIED;
|
return X_STATUS_ACCESS_DENIED;
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,45 +63,28 @@ X_STATUS STFSContainerEntry::QueryDirectory(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto current_buf = (uint8_t*)out_info;
|
auto end = (uint8_t*)out_info + length;
|
||||||
auto end = current_buf + length;
|
|
||||||
|
|
||||||
XDirectoryInfo* current = (XDirectoryInfo*)current_buf;
|
auto entry = *stfs_entry_iterator_;
|
||||||
if (((uint8_t*)¤t->file_name[0]) + xestrlena((*stfs_entry_iterator_)->name.c_str()) > end) {
|
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();
|
stfs_entry_iterator_ = stfs_entry_->children.end();
|
||||||
return X_STATUS_UNSUCCESSFUL;
|
return X_STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
out_info->file_index = 0xCDCDCDCD;
|
||||||
auto entry = *stfs_entry_iterator_;
|
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*)¤t->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;
|
return X_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,12 +39,14 @@ SHIM_CALL NtCreateFile_shim(
|
||||||
|
|
||||||
X_OBJECT_ATTRIBUTES attrs(SHIM_MEM_BASE, object_attributes_ptr);
|
X_OBJECT_ATTRIBUTES attrs(SHIM_MEM_BASE, object_attributes_ptr);
|
||||||
|
|
||||||
|
char* object_name = attrs.object_name.Duplicate();
|
||||||
|
|
||||||
XELOGD(
|
XELOGD(
|
||||||
"NtCreateFile(%.8X, %.8X, %.8X(%s), %.8X, %.8X, %.8X, %d, %d)",
|
"NtCreateFile(%.8X, %.8X, %.8X(%s), %.8X, %.8X, %.8X, %d, %d)",
|
||||||
handle_ptr,
|
handle_ptr,
|
||||||
desired_access,
|
desired_access,
|
||||||
object_attributes_ptr,
|
object_attributes_ptr,
|
||||||
attrs.object_name.buffer,
|
!object_name ? "(null)" : object_name,
|
||||||
io_status_block_ptr,
|
io_status_block_ptr,
|
||||||
allocation_size_ptr,
|
allocation_size_ptr,
|
||||||
file_attributes,
|
file_attributes,
|
||||||
|
@ -69,11 +71,17 @@ SHIM_CALL NtCreateFile_shim(
|
||||||
attrs.root_directory, (XObject**)&root_file);
|
attrs.root_directory, (XObject**)&root_file);
|
||||||
XEASSERT(XSUCCEEDED(result));
|
XEASSERT(XSUCCEEDED(result));
|
||||||
XEASSERT(root_file->type() == XObject::Type::kTypeFile);
|
XEASSERT(root_file->type() == XObject::Type::kTypeFile);
|
||||||
XEASSERTALWAYS();
|
|
||||||
|
auto root_path = root_file->absolute_path();
|
||||||
|
auto target_path = xestrdupa((std::string(root_path) + std::string(object_name)).c_str());
|
||||||
|
entry = fs->ResolvePath(target_path);
|
||||||
|
xe_free(target_path);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Resolve the file using the virtual file system.
|
||||||
|
entry = fs->ResolvePath(object_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolve the file using the virtual file system.
|
|
||||||
entry = fs->ResolvePath(attrs.object_name.buffer);
|
|
||||||
XFile* file = NULL;
|
XFile* file = NULL;
|
||||||
if (entry && entry->type() == Entry::kTypeFile) {
|
if (entry && entry->type() == Entry::kTypeFile) {
|
||||||
// Open the file.
|
// Open the file.
|
||||||
|
@ -104,6 +112,8 @@ SHIM_CALL NtCreateFile_shim(
|
||||||
SHIM_SET_MEM_32(handle_ptr, handle);
|
SHIM_SET_MEM_32(handle_ptr, handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xe_free(object_name);
|
||||||
SHIM_SET_RETURN(result);
|
SHIM_SET_RETURN(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,12 +127,14 @@ SHIM_CALL NtOpenFile_shim(
|
||||||
|
|
||||||
X_OBJECT_ATTRIBUTES attrs(SHIM_MEM_BASE, object_attributes_ptr);
|
X_OBJECT_ATTRIBUTES attrs(SHIM_MEM_BASE, object_attributes_ptr);
|
||||||
|
|
||||||
|
char* object_name = attrs.object_name.Duplicate();
|
||||||
|
|
||||||
XELOGD(
|
XELOGD(
|
||||||
"NtOpenFile(%.8X, %.8X, %.8X(%s), %.8X, %d)",
|
"watNtOpenFile(%.8X, %.8X, %.8X(%s), %.8X, %d)",
|
||||||
handle_ptr,
|
handle_ptr,
|
||||||
desired_access,
|
desired_access,
|
||||||
object_attributes_ptr,
|
object_attributes_ptr,
|
||||||
attrs.object_name.buffer,
|
!object_name ? "(null)" : object_name,
|
||||||
io_status_block_ptr,
|
io_status_block_ptr,
|
||||||
open_options);
|
open_options);
|
||||||
|
|
||||||
|
@ -141,7 +153,7 @@ SHIM_CALL NtOpenFile_shim(
|
||||||
|
|
||||||
// Resolve the file using the virtual file system.
|
// Resolve the file using the virtual file system.
|
||||||
FileSystem* fs = state->file_system();
|
FileSystem* fs = state->file_system();
|
||||||
Entry* entry = fs->ResolvePath(attrs.object_name.buffer);
|
Entry* entry = fs->ResolvePath(object_name);
|
||||||
XFile* file = NULL;
|
XFile* file = NULL;
|
||||||
if (entry && entry->type() == Entry::kTypeFile) {
|
if (entry && entry->type() == Entry::kTypeFile) {
|
||||||
// Open the file.
|
// Open the file.
|
||||||
|
@ -173,6 +185,8 @@ SHIM_CALL NtOpenFile_shim(
|
||||||
SHIM_SET_MEM_32(handle_ptr, handle);
|
SHIM_SET_MEM_32(handle_ptr, handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xe_free(object_name);
|
||||||
SHIM_SET_RETURN(result);
|
SHIM_SET_RETURN(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -445,10 +459,12 @@ SHIM_CALL NtQueryFullAttributesFile_shim(
|
||||||
|
|
||||||
X_OBJECT_ATTRIBUTES attrs(SHIM_MEM_BASE, object_attributes_ptr);
|
X_OBJECT_ATTRIBUTES attrs(SHIM_MEM_BASE, object_attributes_ptr);
|
||||||
|
|
||||||
|
char* object_name = attrs.object_name.Duplicate();
|
||||||
|
|
||||||
XELOGD(
|
XELOGD(
|
||||||
"NtQueryFullAttributesFile(%.8X(%s), %.8X)",
|
"NtQueryFullAttributesFile(%.8X(%s), %.8X)",
|
||||||
object_attributes_ptr,
|
object_attributes_ptr,
|
||||||
attrs.object_name.buffer,
|
!object_name ? "(null)" : object_name,
|
||||||
file_info_ptr);
|
file_info_ptr);
|
||||||
|
|
||||||
X_STATUS result = X_STATUS_NO_SUCH_FILE;
|
X_STATUS result = X_STATUS_NO_SUCH_FILE;
|
||||||
|
@ -464,7 +480,7 @@ SHIM_CALL NtQueryFullAttributesFile_shim(
|
||||||
|
|
||||||
// Resolve the file using the virtual file system.
|
// Resolve the file using the virtual file system.
|
||||||
FileSystem* fs = state->file_system();
|
FileSystem* fs = state->file_system();
|
||||||
Entry* entry = fs->ResolvePath(attrs.object_name.buffer);
|
Entry* entry = fs->ResolvePath(object_name);
|
||||||
if (entry && entry->type() == Entry::kTypeFile) {
|
if (entry && entry->type() == Entry::kTypeFile) {
|
||||||
// Found.
|
// Found.
|
||||||
XFileInfo file_info;
|
XFileInfo file_info;
|
||||||
|
@ -474,6 +490,7 @@ SHIM_CALL NtQueryFullAttributesFile_shim(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xe_free(object_name);
|
||||||
SHIM_SET_RETURN(result);
|
SHIM_SET_RETURN(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -497,10 +514,11 @@ SHIM_CALL NtQueryDirectoryFile_shim(
|
||||||
uint32_t file_info_ptr = SHIM_GET_ARG_32(5);
|
uint32_t file_info_ptr = SHIM_GET_ARG_32(5);
|
||||||
uint32_t length = SHIM_GET_ARG_32(6);
|
uint32_t length = SHIM_GET_ARG_32(6);
|
||||||
uint32_t file_name_ptr = SHIM_GET_ARG_32(7);
|
uint32_t file_name_ptr = SHIM_GET_ARG_32(7);
|
||||||
uint32_t restart_scan = SHIM_GET_ARG_32(8);
|
uint64_t sp = ppc_state->r[1];
|
||||||
|
uint32_t restart_scan = SHIM_MEM_32(sp + 0x54);
|
||||||
|
|
||||||
XELOGD(
|
XELOGD(
|
||||||
"NtQueryDirectoryFile(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X, %d, %.8X)",
|
"NtQueryDirectoryFile(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X, %d, %.8X, %d)",
|
||||||
file_handle,
|
file_handle,
|
||||||
event_handle,
|
event_handle,
|
||||||
apc_routine,
|
apc_routine,
|
||||||
|
@ -508,7 +526,8 @@ SHIM_CALL NtQueryDirectoryFile_shim(
|
||||||
io_status_block_ptr,
|
io_status_block_ptr,
|
||||||
file_info_ptr,
|
file_info_ptr,
|
||||||
length,
|
length,
|
||||||
file_name_ptr);
|
file_name_ptr,
|
||||||
|
restart_scan);
|
||||||
|
|
||||||
if (length < 72) {
|
if (length < 72) {
|
||||||
SHIM_SET_RETURN(X_STATUS_INFO_LENGTH_MISMATCH);
|
SHIM_SET_RETURN(X_STATUS_INFO_LENGTH_MISMATCH);
|
||||||
|
|
|
@ -34,6 +34,8 @@ typedef uint32_t X_STATUS;
|
||||||
#define X_STATUS_TIMEOUT ((X_STATUS)0x00000102L)
|
#define X_STATUS_TIMEOUT ((X_STATUS)0x00000102L)
|
||||||
#define X_STATUS_PENDING ((X_STATUS)0x00000103L)
|
#define X_STATUS_PENDING ((X_STATUS)0x00000103L)
|
||||||
#define X_STATUS_TIMER_RESUME_IGNORED ((X_STATUS)0x40000025L)
|
#define X_STATUS_TIMER_RESUME_IGNORED ((X_STATUS)0x40000025L)
|
||||||
|
#define X_STATUS_BUFFER_OVERFLOW ((X_STATUS)0x80000005L)
|
||||||
|
#define X_STATUS_NO_MORE_FILES ((X_STATUS)0x80000006L)
|
||||||
#define X_STATUS_UNSUCCESSFUL ((X_STATUS)0xC0000001L)
|
#define X_STATUS_UNSUCCESSFUL ((X_STATUS)0xC0000001L)
|
||||||
#define X_STATUS_NOT_IMPLEMENTED ((X_STATUS)0xC0000002L)
|
#define X_STATUS_NOT_IMPLEMENTED ((X_STATUS)0xC0000002L)
|
||||||
#define X_STATUS_INFO_LENGTH_MISMATCH ((X_STATUS)0xC0000004L)
|
#define X_STATUS_INFO_LENGTH_MISMATCH ((X_STATUS)0xC0000004L)
|
||||||
|
@ -202,11 +204,12 @@ typedef enum _X_FILE_INFORMATION_CLASS {
|
||||||
|
|
||||||
|
|
||||||
class X_ANSI_STRING {
|
class X_ANSI_STRING {
|
||||||
public:
|
private:
|
||||||
uint16_t length;
|
uint16_t length;
|
||||||
uint16_t maximum_length;
|
uint16_t maximum_length;
|
||||||
char* buffer;
|
const char* buffer;
|
||||||
|
|
||||||
|
public:
|
||||||
X_ANSI_STRING() {
|
X_ANSI_STRING() {
|
||||||
Zero();
|
Zero();
|
||||||
}
|
}
|
||||||
|
@ -217,7 +220,7 @@ public:
|
||||||
length = XEGETUINT16BE(base + p);
|
length = XEGETUINT16BE(base + p);
|
||||||
maximum_length = XEGETUINT16BE(base + p + 2);
|
maximum_length = XEGETUINT16BE(base + p + 2);
|
||||||
if (maximum_length) {
|
if (maximum_length) {
|
||||||
buffer = (char*)(base + XEGETUINT32BE(base + p + 4));
|
buffer = (const char*)(base + XEGETUINT32BE(base + p + 4));
|
||||||
} else {
|
} else {
|
||||||
buffer = 0;
|
buffer = 0;
|
||||||
}
|
}
|
||||||
|
@ -226,6 +229,14 @@ public:
|
||||||
length = maximum_length = 0;
|
length = maximum_length = 0;
|
||||||
buffer = 0;
|
buffer = 0;
|
||||||
}
|
}
|
||||||
|
char* Duplicate() {
|
||||||
|
if (buffer == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
auto copy = (char*)xe_calloc(length+1);
|
||||||
|
xestrncpya(copy, length+1, buffer, length);
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -266,20 +277,20 @@ typedef enum _X_INPUT_FLAG {
|
||||||
} X_INPUT_FLAG;
|
} X_INPUT_FLAG;
|
||||||
|
|
||||||
typedef enum _X_INPUT_GAMEPAD_BUTTON {
|
typedef enum _X_INPUT_GAMEPAD_BUTTON {
|
||||||
X_INPUT_GAMEPAD_DPAD_UP = 0x0001,
|
X_INPUT_GAMEPAD_DPAD_UP = 0x0001,
|
||||||
X_INPUT_GAMEPAD_DPAD_DOWN = 0x0002,
|
X_INPUT_GAMEPAD_DPAD_DOWN = 0x0002,
|
||||||
X_INPUT_GAMEPAD_DPAD_LEFT = 0x0004,
|
X_INPUT_GAMEPAD_DPAD_LEFT = 0x0004,
|
||||||
X_INPUT_GAMEPAD_DPAD_RIGHT = 0x0008,
|
X_INPUT_GAMEPAD_DPAD_RIGHT = 0x0008,
|
||||||
X_INPUT_GAMEPAD_START = 0x0010,
|
X_INPUT_GAMEPAD_START = 0x0010,
|
||||||
X_INPUT_GAMEPAD_BACK = 0x0020,
|
X_INPUT_GAMEPAD_BACK = 0x0020,
|
||||||
X_INPUT_GAMEPAD_LEFT_THUMB = 0x0040,
|
X_INPUT_GAMEPAD_LEFT_THUMB = 0x0040,
|
||||||
X_INPUT_GAMEPAD_RIGHT_THUMB = 0x0080,
|
X_INPUT_GAMEPAD_RIGHT_THUMB = 0x0080,
|
||||||
X_INPUT_GAMEPAD_LEFT_SHOULDER = 0x0100,
|
X_INPUT_GAMEPAD_LEFT_SHOULDER = 0x0100,
|
||||||
X_INPUT_GAMEPAD_RIGHT_SHOULDER = 0x0200,
|
X_INPUT_GAMEPAD_RIGHT_SHOULDER = 0x0200,
|
||||||
X_INPUT_GAMEPAD_A = 0x1000,
|
X_INPUT_GAMEPAD_A = 0x1000,
|
||||||
X_INPUT_GAMEPAD_B = 0x2000,
|
X_INPUT_GAMEPAD_B = 0x2000,
|
||||||
X_INPUT_GAMEPAD_X = 0x4000,
|
X_INPUT_GAMEPAD_X = 0x4000,
|
||||||
X_INPUT_GAMEPAD_Y = 0x8000,
|
X_INPUT_GAMEPAD_Y = 0x8000,
|
||||||
} X_INPUT_GAMEPAD_BUTTON;
|
} X_INPUT_GAMEPAD_BUTTON;
|
||||||
|
|
||||||
class X_INPUT_GAMEPAD {
|
class X_INPUT_GAMEPAD {
|
||||||
|
|
Loading…
Reference in New Issue