diff --git a/Core/FileSystems/ISOFileSystem.cpp b/Core/FileSystems/ISOFileSystem.cpp index 4b9aa8b09f..731a2f48a9 100644 --- a/Core/FileSystems/ISOFileSystem.cpp +++ b/Core/FileSystems/ISOFileSystem.cpp @@ -467,7 +467,7 @@ int ISOFileSystem::Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outd // Get ISO9660 volume descriptor (from open ISO9660 file.) case 0x01020001: if (e.isBlockSectorMode) { - ERROR_LOG(FILESYS, "Unsupported 0x01020001 command on a umd block device"); + ERROR_LOG(FILESYS, "Unsupported read volume descriptor command on a umd block device"); return SCE_KERNEL_ERROR_ERRNO_FUNCTION_NOT_SUPPORTED; } @@ -477,8 +477,38 @@ int ISOFileSystem::Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outd } INFO_LOG(SCEIO, "sceIoIoctl: reading ISO9660 volume descriptor read"); - blockDevice->ReadBlock(0x10, Memory::GetPointer(outdataPtr)); + blockDevice->ReadBlock(16, Memory::GetPointer(outdataPtr)); return 0; + + // Get ISO9660 path table (from open ISO9660 file.) + case 0x01020002: + if (e.isBlockSectorMode) { + ERROR_LOG(FILESYS, "Unsupported read path table command on a umd block device"); + return SCE_KERNEL_ERROR_ERRNO_FUNCTION_NOT_SUPPORTED; + } + + VolDescriptor desc; + blockDevice->ReadBlock(16, (u8 *)&desc); + if (outlen < (u32)desc.pathTableLengthLE) { + return SCE_KERNEL_ERROR_ERRNO_INVALID_ARGUMENT; + } else { + int block = (u16)desc.firstLETableSectorLE; + u32 size = (u32)desc.pathTableLengthLE; + u8 *out = Memory::GetPointer(outdataPtr); + + while (size >= 2048) { + blockDevice->ReadBlock(block++, out); + out += 2048; + } + + // The remaining (or, usually, only) partial sector. + if (size > 0) { + u8 temp[2048]; + blockDevice->ReadBlock(block, temp); + memcpy(out, temp, size); + } + return 0; + } } return SCE_KERNEL_ERROR_ERRNO_FUNCTION_NOT_SUPPORTED; } diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index ce085e37f6..60ab61ec0e 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -1979,21 +1979,6 @@ int __IoIoctl(u32 id, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 out return (int)f->info.size; break; - // Get ISO9660 path table (from open ISO9660 file.) - case 0x01020002: - // TODO: Should not work for umd0:/, ms0:/, etc. - // Seems like it will accept an out size > path table size, but only write path table bytes. - // If not big enough, returns SCE_KERNEL_ERROR_ERRNO_INVALID_ARGUMENT. - // Probably only the LE version. - { - char temp[256]; - // We want the reported message to include the cmd, so it's unique. - sprintf(temp, "sceIoIoctl(%%s, %08x, %%08x, %%x, %%08x, %%x)", cmd); - Reporting::ReportMessage(temp, f->fullpath.c_str(), indataPtr, inlen, outdataPtr, outlen); - ERROR_LOG(SCEIO, "UNIMPL 0=sceIoIoctl id: %08x, cmd %08x, indataPtr %08x, inlen %08x, outdataPtr %08x, outLen %08x", id,cmd,indataPtr,inlen,outdataPtr,outlen); - } - break; - // Get UMD sector size case 0x01020003: // TODO: Should not work for umd0:/, ms0:/, etc.