diff --git a/Core/FileSystems/DirectoryFileSystem.cpp b/Core/FileSystems/DirectoryFileSystem.cpp index 73fd5b6c6d..9cbad4ccb4 100644 --- a/Core/FileSystems/DirectoryFileSystem.cpp +++ b/Core/FileSystems/DirectoryFileSystem.cpp @@ -493,6 +493,11 @@ int DirectoryFileSystem::Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u3 return SCE_KERNEL_ERROR_ERRNO_FUNCTION_NOT_SUPPORTED; } +int DirectoryFileSystem::DevType(u32 handle) { + EntryMap::iterator iter = entries.find(handle); + return PSP_DEV_TYPE_FILE; +} + size_t DirectoryFileSystem::ReadFile(u32 handle, u8 *pointer, s64 size) { EntryMap::iterator iter = entries.find(handle); if (iter != entries.end()) @@ -775,6 +780,11 @@ int VFSFileSystem::Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outd return SCE_KERNEL_ERROR_ERRNO_FUNCTION_NOT_SUPPORTED; } +int VFSFileSystem::DevType(u32 handle) { + EntryMap::iterator iter = entries.find(handle); + return PSP_DEV_TYPE_FILE; +} + size_t VFSFileSystem::ReadFile(u32 handle, u8 *pointer, s64 size) { INFO_LOG(FILESYS,"VFSFileSystem::ReadFile %08x %p %i", handle, pointer, (u32)size); EntryMap::iterator iter = entries.find(handle); diff --git a/Core/FileSystems/DirectoryFileSystem.h b/Core/FileSystems/DirectoryFileSystem.h index bfb9ad3cc6..9a669a639d 100644 --- a/Core/FileSystems/DirectoryFileSystem.h +++ b/Core/FileSystems/DirectoryFileSystem.h @@ -96,6 +96,7 @@ public: PSPFileInfo GetFileInfo(std::string filename); bool OwnsHandle(u32 handle); int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec); + int DevType(u32 handle); bool MkDir(const std::string &dirname); bool RmDir(const std::string &dirname); @@ -134,6 +135,7 @@ public: PSPFileInfo GetFileInfo(std::string filename); bool OwnsHandle(u32 handle); int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec); + int DevType(u32 handle); bool MkDir(const std::string &dirname); bool RmDir(const std::string &dirname); diff --git a/Core/FileSystems/FileSystem.h b/Core/FileSystems/FileSystem.h index 75c80ac5cc..0494af6e73 100644 --- a/Core/FileSystems/FileSystem.h +++ b/Core/FileSystems/FileSystem.h @@ -43,6 +43,13 @@ enum FileType FILETYPE_DIRECTORY=2 }; +enum DevType +{ + PSP_DEV_TYPE_BLOCK = 0x04, + PSP_DEV_TYPE_FILE = 0x10, + PSP_DEV_TYPE_ALIAS = 0x20, +}; + class IHandleAllocator { public: @@ -122,6 +129,7 @@ public: virtual bool RemoveFile(const std::string &filename) = 0; virtual bool GetHostPath(const std::string &inpath, std::string &outpath) = 0; virtual int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) = 0; + virtual int DevType(u32 handle) = 0; }; @@ -143,6 +151,7 @@ public: virtual bool RemoveFile(const std::string &filename) {return false;} virtual bool GetHostPath(const std::string &inpath, std::string &outpath) {return false;} virtual int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) {return SCE_KERNEL_ERROR_ERRNO_FUNCTION_NOT_SUPPORTED; } + virtual int DevType(u32 handle) {return 0;} }; diff --git a/Core/FileSystems/ISOFileSystem.cpp b/Core/FileSystems/ISOFileSystem.cpp index 731a2f48a9..c2c2ebdce8 100644 --- a/Core/FileSystems/ISOFileSystem.cpp +++ b/Core/FileSystems/ISOFileSystem.cpp @@ -513,6 +513,12 @@ int ISOFileSystem::Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outd return SCE_KERNEL_ERROR_ERRNO_FUNCTION_NOT_SUPPORTED; } +int ISOFileSystem::DevType(u32 handle) +{ + EntryMap::iterator iter = entries.find(handle); + return iter->second.isBlockSectorMode ? PSP_DEV_TYPE_BLOCK : PSP_DEV_TYPE_FILE; +} + size_t ISOFileSystem::ReadFile(u32 handle, u8 *pointer, s64 size) { EntryMap::iterator iter = entries.find(handle); diff --git a/Core/FileSystems/ISOFileSystem.h b/Core/FileSystems/ISOFileSystem.h index 0c46bb1924..78ae4003b9 100644 --- a/Core/FileSystems/ISOFileSystem.h +++ b/Core/FileSystems/ISOFileSystem.h @@ -40,6 +40,7 @@ public: PSPFileInfo GetFileInfo(std::string filename); bool OwnsHandle(u32 handle); int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec); + int DevType(u32 handle); size_t WriteFile(u32 handle, const u8 *pointer, s64 size); bool GetHostPath(const std::string &inpath, std::string &outpath) {return false;} diff --git a/Core/FileSystems/MetaFileSystem.cpp b/Core/FileSystems/MetaFileSystem.cpp index 7726d51dc2..34123f690c 100644 --- a/Core/FileSystems/MetaFileSystem.cpp +++ b/Core/FileSystems/MetaFileSystem.cpp @@ -488,6 +488,15 @@ int MetaFileSystem::Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 out return SCE_KERNEL_ERROR_ERROR; } +int MetaFileSystem::DevType(u32 handle) +{ + lock_guard guard(lock); + IFileSystem *sys = GetHandleOwner(handle); + if (sys) + return sys->DevType(handle); + return SCE_KERNEL_ERROR_ERROR; +} + void MetaFileSystem::CloseFile(u32 handle) { lock_guard guard(lock); diff --git a/Core/FileSystems/MetaFileSystem.h b/Core/FileSystems/MetaFileSystem.h index 78b7a0d44d..2b9515f44d 100644 --- a/Core/FileSystems/MetaFileSystem.h +++ b/Core/FileSystems/MetaFileSystem.h @@ -103,6 +103,7 @@ public: virtual int RenameFile(const std::string &from, const std::string &to); virtual bool RemoveFile(const std::string &filename); virtual int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec); + virtual int DevType(u32 handle); // Convenience helper - returns < 0 on failure. int ReadEntireFile(const std::string &filename, std::vector &data); diff --git a/Core/FileSystems/VirtualDiscFileSystem.cpp b/Core/FileSystems/VirtualDiscFileSystem.cpp index 59749cc5fa..84974436ac 100644 --- a/Core/FileSystems/VirtualDiscFileSystem.cpp +++ b/Core/FileSystems/VirtualDiscFileSystem.cpp @@ -503,6 +503,11 @@ int VirtualDiscFileSystem::Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, return SCE_KERNEL_ERROR_ERRNO_FUNCTION_NOT_SUPPORTED; } +int VirtualDiscFileSystem::DevType(u32 handle) { + EntryMap::iterator iter = entries.find(handle); + return iter->second.type == VFILETYPE_ISO ? PSP_DEV_TYPE_BLOCK : PSP_DEV_TYPE_FILE; +} + PSPFileInfo VirtualDiscFileSystem::GetFileInfo(std::string filename) { PSPFileInfo x; x.name = filename; diff --git a/Core/FileSystems/VirtualDiscFileSystem.h b/Core/FileSystems/VirtualDiscFileSystem.h index 85701f6e73..09a3d488e1 100644 --- a/Core/FileSystems/VirtualDiscFileSystem.h +++ b/Core/FileSystems/VirtualDiscFileSystem.h @@ -37,6 +37,7 @@ public: PSPFileInfo GetFileInfo(std::string filename); bool OwnsHandle(u32 handle); int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec); + int DevType(u32 handle); bool GetHostPath(const std::string &inpath, std::string &outpath); std::vector GetDirListing(std::string path); diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 60ab61ec0e..c2e622ccf5 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -59,8 +59,6 @@ const int ERROR_KERNEL_BAD_FILE_DESCRIPTOR = 0x80020323; const int ERROR_PGD_INVALID_HEADER = 0x80510204; -#define PSP_DEV_TYPE_ALIAS 0x20 - /* TODO: async io is missing features! @@ -107,6 +105,9 @@ typedef u64 SceIores; const int PSP_COUNT_FDS = 64; // TODO: Should be 3, and stdin/stdout/stderr are special values aliased to 0? const int PSP_MIN_FD = 4; +const int PSP_STDOUT = 1; +const int PSP_STDERR = 2; +const int PSP_STDIN = 3; static int asyncNotifyEvent = -1; static int syncNotifyEvent = -1; static SceUID fds[PSP_COUNT_FDS]; @@ -553,22 +554,22 @@ u32 sceIoUnassign(const char *alias) u32 sceKernelStdin() { // fix Buzz Ultimate Music Quiz Crash Sporadically,issue#4497 hleEatCycles(1); - DEBUG_LOG(SCEIO, "3=sceKernelStdin()"); - return 3; + DEBUG_LOG(SCEIO, "%d=sceKernelStdin()", PSP_STDIN); + return PSP_STDIN; } u32 sceKernelStdout() { // fix Buzz Ultimate Music Quiz Crash Sporadically,issue#4497 hleEatCycles(1); - DEBUG_LOG(SCEIO, "1=sceKernelStdout()"); - return 1; + DEBUG_LOG(SCEIO, "%d=sceKernelStdout()", PSP_STDOUT); + return PSP_STDOUT; } u32 sceKernelStderr() { // fix Buzz Ultimate Music Quiz Crash Sporadically,issue#4497 hleEatCycles(1); - DEBUG_LOG(SCEIO, "2=sceKernelStderr()"); - return 2; + DEBUG_LOG(SCEIO, "%d=sceKernelStderr()", PSP_STDERR); + return PSP_STDERR; } void __IoCompleteAsyncIO(int fd) { @@ -714,7 +715,7 @@ u32 npdrmRead(FileNode *f, u8 *data, int size) { } bool __IoRead(int &result, int id, u32 data_addr, int size) { - if (id == 3) { + if (id == PSP_STDIN) { DEBUG_LOG(SCEIO, "sceIoRead STDIN"); return 0; //stdin } @@ -828,7 +829,7 @@ u32 sceIoReadAsync(int id, u32 data_addr, int size) { bool __IoWrite(int &result, int id, u32 data_addr, int size) { const void *data_ptr = Memory::GetPointer(data_addr); // Let's handle stdout/stderr specially. - if (id == 1 || id == 2) { + if (id == PSP_STDOUT || id == PSP_STDERR) { const char *str = (const char *) data_ptr; const int str_size = size == 0 ? 0 : (str[size - 1] == '\n' ? size - 1 : size); INFO_LOG(SCEIO, "%s: %.*s", id == 1 ? "stdout" : "stderr", str_size, str); @@ -935,15 +936,20 @@ u32 sceIoWriteAsync(int id, u32 data_addr, int size) { } } -u32 sceIoGetDevType(int id) -{ - ERROR_LOG_REPORT(SCEIO, "UNIMPL sceIoGetDevType(%d)", id); +u32 sceIoGetDevType(int id) { + if (id == PSP_STDOUT || id == PSP_STDERR || id == PSP_STDIN) { + DEBUG_LOG(SCEIO, "sceIoGetDevType(%d)", id); + return PSP_DEV_TYPE_FILE; + } + u32 error; FileNode *f = __IoGetFd(id, error); int result; - if (f) - result = PSP_DEV_TYPE_ALIAS; - else { + if (f) { + // TODO: When would this return PSP_DEV_TYPE_ALIAS? + WARN_LOG(SCEIO, "sceIoGetDevType(%d - %s)", id, f->fullpath.c_str()); + result = pspFileSystem.DevType(f->handle); + } else { ERROR_LOG(SCEIO, "sceIoGetDevType: unknown id %d", id); result = ERROR_KERNEL_BAD_FILE_DESCRIPTOR; }