commit
a52fcf0157
|
@ -469,30 +469,34 @@ SHIM_CALL NtSetInformationFile_shim(PPCContext* ppc_context,
|
||||||
SHIM_SET_RETURN_32(result);
|
SHIM_SET_RETURN_32(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
SHIM_CALL NtQueryInformationFile_shim(PPCContext* ppc_context,
|
struct X_IO_STATUS_BLOCK {
|
||||||
KernelState* kernel_state) {
|
union {
|
||||||
uint32_t file_handle = SHIM_GET_ARG_32(0);
|
xe::be<uint32_t> status;
|
||||||
uint32_t io_status_block_ptr = SHIM_GET_ARG_32(1);
|
xe::be<uint32_t> pointer;
|
||||||
uint32_t file_info_ptr = SHIM_GET_ARG_32(2);
|
};
|
||||||
uint32_t length = SHIM_GET_ARG_32(3);
|
xe::be<uint32_t> information;
|
||||||
uint32_t file_info_class = SHIM_GET_ARG_32(4);
|
};
|
||||||
|
|
||||||
XELOGD("NtQueryInformationFile(%.8X, %.8X, %.8X, %.8X, %.8X)", file_handle,
|
|
||||||
io_status_block_ptr, file_info_ptr, length, file_info_class);
|
|
||||||
|
|
||||||
|
dword_result_t NtQueryInformationFile(dword_t file_handle,
|
||||||
|
pointer_t<X_IO_STATUS_BLOCK>
|
||||||
|
io_status_block_ptr,
|
||||||
|
lpvoid_t file_info_ptr, dword_t length,
|
||||||
|
dword_t file_info_class) {
|
||||||
X_STATUS result = X_STATUS_SUCCESS;
|
X_STATUS result = X_STATUS_SUCCESS;
|
||||||
uint32_t info = 0;
|
uint32_t info = 0;
|
||||||
|
|
||||||
// Grab file.
|
// Grab file.
|
||||||
auto file = kernel_state->object_table()->LookupObject<XFile>(file_handle);
|
auto file = kernel_state()->object_table()->LookupObject<XFile>(file_handle);
|
||||||
if (file) {
|
if (file) {
|
||||||
switch (file_info_class) {
|
switch (file_info_class) {
|
||||||
case XFileInternalInformation:
|
case XFileInternalInformation:
|
||||||
// Internal unique file pointer. Not sure why anyone would want this.
|
// Internal unique file pointer. Not sure why anyone would want this.
|
||||||
assert_true(length == 8);
|
assert_true(length == 8);
|
||||||
info = 8;
|
info = 8;
|
||||||
|
|
||||||
// TODO(benvanik): use pointer to fs:: entry?
|
// TODO(benvanik): use pointer to fs:: entry?
|
||||||
SHIM_SET_MEM_64(file_info_ptr, xe::hash_combine(0, file->path()));
|
xe::store_and_swap<uint64_t>(file_info_ptr,
|
||||||
|
xe::hash_combine(0, file->path()));
|
||||||
break;
|
break;
|
||||||
case XFilePositionInformation:
|
case XFilePositionInformation:
|
||||||
// struct FILE_POSITION_INFORMATION {
|
// struct FILE_POSITION_INFORMATION {
|
||||||
|
@ -500,7 +504,8 @@ SHIM_CALL NtQueryInformationFile_shim(PPCContext* ppc_context,
|
||||||
// };
|
// };
|
||||||
assert_true(length == 8);
|
assert_true(length == 8);
|
||||||
info = 8;
|
info = 8;
|
||||||
SHIM_SET_MEM_64(file_info_ptr, file->position());
|
|
||||||
|
xe::store_and_swap<uint64_t>(file_info_ptr, file->position());
|
||||||
break;
|
break;
|
||||||
case XFileNetworkOpenInformation: {
|
case XFileNetworkOpenInformation: {
|
||||||
// struct FILE_NETWORK_OPEN_INFORMATION {
|
// struct FILE_NETWORK_OPEN_INFORMATION {
|
||||||
|
@ -514,9 +519,8 @@ SHIM_CALL NtQueryInformationFile_shim(PPCContext* ppc_context,
|
||||||
// ULONG Unknown;
|
// ULONG Unknown;
|
||||||
// };
|
// };
|
||||||
assert_true(length == 56);
|
assert_true(length == 56);
|
||||||
auto file_info =
|
|
||||||
kernel_memory()->TranslateVirtual<X_FILE_NETWORK_OPEN_INFORMATION*>(
|
auto file_info = file_info_ptr.as<X_FILE_NETWORK_OPEN_INFORMATION*>();
|
||||||
file_info_ptr);
|
|
||||||
result = file->QueryInfo(file_info);
|
result = file->QueryInfo(file_info);
|
||||||
if (XSUCCEEDED(result)) {
|
if (XSUCCEEDED(result)) {
|
||||||
info = 56;
|
info = 56;
|
||||||
|
@ -543,10 +547,18 @@ SHIM_CALL NtQueryInformationFile_shim(PPCContext* ppc_context,
|
||||||
*/
|
*/
|
||||||
result = X_STATUS_UNSUCCESSFUL;
|
result = X_STATUS_UNSUCCESSFUL;
|
||||||
break;
|
break;
|
||||||
|
case XFileSectorInformation:
|
||||||
|
// TODO: Return sector this file's on.
|
||||||
|
assert_true(length == 4);
|
||||||
|
|
||||||
|
result = X_STATUS_UNSUCCESSFUL;
|
||||||
|
info = 0;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
// Unsupported, for now.
|
// Unsupported, for now.
|
||||||
assert_always();
|
assert_always();
|
||||||
info = 0;
|
info = 0;
|
||||||
|
result = X_STATUS_UNSUCCESSFUL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -554,12 +566,14 @@ SHIM_CALL NtQueryInformationFile_shim(PPCContext* ppc_context,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (io_status_block_ptr) {
|
if (io_status_block_ptr) {
|
||||||
SHIM_SET_MEM_32(io_status_block_ptr, result); // Status
|
io_status_block_ptr->status = result;
|
||||||
SHIM_SET_MEM_32(io_status_block_ptr + 4, info); // Information
|
io_status_block_ptr->information = info; // # bytes written
|
||||||
}
|
}
|
||||||
|
|
||||||
SHIM_SET_RETURN_32(result);
|
return result;
|
||||||
}
|
}
|
||||||
|
DECLARE_XBOXKRNL_EXPORT(NtQueryInformationFile, ExportTag::kImplemented |
|
||||||
|
ExportTag::kFileSystem);
|
||||||
|
|
||||||
SHIM_CALL NtQueryFullAttributesFile_shim(PPCContext* ppc_context,
|
SHIM_CALL NtQueryFullAttributesFile_shim(PPCContext* ppc_context,
|
||||||
KernelState* kernel_state) {
|
KernelState* kernel_state) {
|
||||||
|
@ -774,7 +788,6 @@ void xe::kernel::xboxkrnl::RegisterIoExports(
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", NtOpenFile, state);
|
SHIM_SET_MAPPING("xboxkrnl.exe", NtOpenFile, state);
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", NtReadFile, state);
|
SHIM_SET_MAPPING("xboxkrnl.exe", NtReadFile, state);
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", NtWriteFile, state);
|
SHIM_SET_MAPPING("xboxkrnl.exe", NtWriteFile, state);
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", NtQueryInformationFile, state);
|
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", NtSetInformationFile, state);
|
SHIM_SET_MAPPING("xboxkrnl.exe", NtSetInformationFile, state);
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", NtQueryFullAttributesFile, state);
|
SHIM_SET_MAPPING("xboxkrnl.exe", NtQueryFullAttributesFile, state);
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", NtQueryVolumeInformationFile, state);
|
SHIM_SET_MAPPING("xboxkrnl.exe", NtQueryVolumeInformationFile, state);
|
||||||
|
|
Loading…
Reference in New Issue