mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-09 04:26:26 +02:00
Merge pull request #5871 from hrydgard/sceiodread_ms0check
More elegant way of solving #5839 (d_private in sceIoDread)
This commit is contained in:
commit
27708d6f97
8 files changed
+59
-13
No files matched your search
@@ -134,6 +134,11 @@ bool FixPathCase(std::string& basePath, std::string &path, FixPathCaseBehavior b
|
||||
|
||||
#endif
|
||||
|
||||
DirectoryFileSystem::DirectoryFileSystem(IHandleAllocator *_hAlloc, std::string _basePath, int _flags) : basePath(_basePath), flags(_flags) {
|
||||
File::CreateFullPath(basePath);
|
||||
hAlloc = _hAlloc;
|
||||
}
|
||||
|
||||
std::string DirectoryFileHandle::GetLocalPath(std::string& basePath, std::string localpath)
|
||||
{
|
||||
if (localpath.empty())
|
||||
@@ -326,11 +331,6 @@ void DirectoryFileHandle::Close()
|
||||
#endif
|
||||
}
|
||||
|
||||
DirectoryFileSystem::DirectoryFileSystem(IHandleAllocator *_hAlloc, std::string _basePath) : basePath(_basePath) {
|
||||
File::CreateFullPath(basePath);
|
||||
hAlloc = _hAlloc;
|
||||
}
|
||||
|
||||
void DirectoryFileSystem::CloseAll() {
|
||||
for (auto iter = entries.begin(); iter != entries.end(); ++iter) {
|
||||
iter->second.hFile.Close();
|
||||
|
||||
@@ -86,7 +86,7 @@ struct DirectoryFileHandle
|
||||
|
||||
class DirectoryFileSystem : public IFileSystem {
|
||||
public:
|
||||
DirectoryFileSystem(IHandleAllocator *_hAlloc, std::string _basePath);
|
||||
DirectoryFileSystem(IHandleAllocator *_hAlloc, std::string _basePath, int _flags = 0);
|
||||
~DirectoryFileSystem();
|
||||
|
||||
void CloseAll();
|
||||
@@ -108,6 +108,7 @@ public:
|
||||
int RenameFile(const std::string &from, const std::string &to);
|
||||
bool RemoveFile(const std::string &filename);
|
||||
bool GetHostPath(const std::string &inpath, std::string &outpath);
|
||||
int Flags() { return flags; }
|
||||
|
||||
private:
|
||||
struct OpenFileEntry {
|
||||
@@ -120,7 +121,7 @@ private:
|
||||
EntryMap entries;
|
||||
std::string basePath;
|
||||
IHandleAllocator *hAlloc;
|
||||
|
||||
int flags;
|
||||
// In case of Windows: Translate slashes, etc.
|
||||
std::string GetLocalPath(std::string localpath);
|
||||
};
|
||||
@@ -149,6 +150,7 @@ public:
|
||||
int RenameFile(const std::string &from, const std::string &to);
|
||||
bool RemoveFile(const std::string &filename);
|
||||
bool GetHostPath(const std::string &inpath, std::string &outpath);
|
||||
int Flags() { return 0; }
|
||||
|
||||
private:
|
||||
struct OpenFileEntry {
|
||||
|
||||
@@ -50,6 +50,10 @@ enum DevType
|
||||
PSP_DEV_TYPE_ALIAS = 0x20,
|
||||
};
|
||||
|
||||
enum FileSystemFlags
|
||||
{
|
||||
FILESYSTEM_SIMULATE_FAT32 = 1,
|
||||
};
|
||||
|
||||
class IHandleAllocator {
|
||||
public:
|
||||
@@ -112,6 +116,7 @@ public:
|
||||
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;
|
||||
virtual int Flags() = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -133,7 +138,8 @@ 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;}
|
||||
virtual int DevType(u32 handle) { return 0; }
|
||||
virtual int Flags() { return 0; }
|
||||
};
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ public:
|
||||
bool OwnsHandle(u32 handle);
|
||||
int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec);
|
||||
int DevType(u32 handle);
|
||||
int Flags() { return 0; }
|
||||
|
||||
size_t WriteFile(u32 handle, const u8 *pointer, s64 size);
|
||||
bool GetHostPath(const std::string &inpath, std::string &outpath) {return false;}
|
||||
|
||||
@@ -255,6 +255,10 @@ std::string MetaFileSystem::NormalizePrefix(std::string prefix) const {
|
||||
if (startsWith(prefix, "host"))
|
||||
prefix = "host0:";
|
||||
|
||||
// Should we simply make this case insensitive?
|
||||
if (prefix == "DISC0:")
|
||||
prefix = "disc0:";
|
||||
|
||||
return prefix;
|
||||
}
|
||||
|
||||
@@ -284,6 +288,13 @@ void MetaFileSystem::Remount(IFileSystem *oldSystem, IFileSystem *newSystem) {
|
||||
}
|
||||
}
|
||||
|
||||
IFileSystem *MetaFileSystem::GetSystemFromFilename(const std::string &filename) {
|
||||
size_t prefixPos = filename.find(':');
|
||||
if (prefixPos == filename.npos)
|
||||
return 0;
|
||||
return GetSystem(filename.substr(0, prefixPos + 1));
|
||||
}
|
||||
|
||||
IFileSystem *MetaFileSystem::GetSystem(const std::string &prefix) {
|
||||
for (auto it = fileSystems.begin(); it != fileSystems.end(); ++it) {
|
||||
if (it->prefix == NormalizePrefix(prefix))
|
||||
|
||||
@@ -54,6 +54,7 @@ public:
|
||||
void Remount(IFileSystem *oldSystem, IFileSystem *newSystem);
|
||||
|
||||
IFileSystem *GetSystem(const std::string &prefix);
|
||||
IFileSystem *GetSystemFromFilename(const std::string &filename);
|
||||
|
||||
void ThreadEnded(int threadID);
|
||||
|
||||
@@ -106,6 +107,7 @@ public:
|
||||
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);
|
||||
virtual int Flags() { return 0; }
|
||||
|
||||
// Convenience helper - returns < 0 on failure.
|
||||
int ReadEntireFile(const std::string &filename, std::vector<u8> &data);
|
||||
|
||||
@@ -40,6 +40,7 @@ public:
|
||||
int DevType(u32 handle);
|
||||
bool GetHostPath(const std::string &inpath, std::string &outpath);
|
||||
std::vector<PSPFileInfo> GetDirListing(std::string path);
|
||||
int Flags() { return 0; }
|
||||
|
||||
// unsupported operations
|
||||
size_t WriteFile(u32 handle, const u8 *pointer, s64 size);
|
||||
|
||||
+28
-5
@@ -457,7 +457,7 @@ void __IoInit() {
|
||||
asyncNotifyEvent = CoreTiming::RegisterEvent("IoAsyncNotify", __IoAsyncNotify);
|
||||
syncNotifyEvent = CoreTiming::RegisterEvent("IoSyncNotify", __IoSyncNotify);
|
||||
|
||||
memstickSystem = new DirectoryFileSystem(&pspFileSystem, g_Config.memCardDirectory);
|
||||
memstickSystem = new DirectoryFileSystem(&pspFileSystem, g_Config.memCardDirectory, FILESYSTEM_SIMULATE_FAT32);
|
||||
#if defined(USING_WIN_UI) || defined(APPLE)
|
||||
flash0System = new DirectoryFileSystem(&pspFileSystem, g_Config.flash0Directory);
|
||||
#else
|
||||
@@ -716,7 +716,7 @@ u32 npdrmRead(FileNode *f, u8 *data, int size) {
|
||||
memcpy(data, pgd->block_buf+offset, copy_size);
|
||||
block += 1;
|
||||
offset = 0;
|
||||
}else{
|
||||
} else {
|
||||
copy_size = remain_size;
|
||||
memcpy(data, pgd->block_buf+offset, copy_size);
|
||||
}
|
||||
@@ -1925,6 +1925,19 @@ u32 sceIoDopen(const char *path) {
|
||||
return id;
|
||||
}
|
||||
|
||||
// For some reason strncpy will fill up the entire output buffer. No reason to do that,
|
||||
// so we use this trivial replacement.
|
||||
static void strcpy_limit(char *dest, const char *src, int limit) {
|
||||
int i;
|
||||
for (i = 0; i < limit - 1; i++) {
|
||||
if (!src[i])
|
||||
break;
|
||||
dest[i] = src[i];
|
||||
}
|
||||
// Always null terminate.
|
||||
dest[i] = 0;
|
||||
}
|
||||
|
||||
u32 sceIoDread(int id, u32 dirent_addr) {
|
||||
u32 error;
|
||||
DirListing *dir = kernelObjects.Get<DirListing>(id, error);
|
||||
@@ -1943,8 +1956,15 @@ u32 sceIoDread(int id, u32 dirent_addr) {
|
||||
strncpy(entry->d_name, info.name.c_str(), 256);
|
||||
entry->d_name[255] = '\0';
|
||||
|
||||
bool isFAT = false;
|
||||
IFileSystem *sys = pspFileSystem.GetSystemFromFilename(dir->name);
|
||||
if (sys && (sys->Flags() & FILESYSTEM_SIMULATE_FAT32))
|
||||
isFAT = true;
|
||||
else
|
||||
isFAT = false;
|
||||
|
||||
// Only write d_private for memory stick
|
||||
if (dir->name.substr(0, 3) == "ms0") {
|
||||
if (isFAT) {
|
||||
// write d_private for supporting Custom BGM
|
||||
// ref JPCSP https://code.google.com/p/jpcsp/source/detail?r=3468
|
||||
if (Memory::IsValidAddress(entry->d_private)){
|
||||
@@ -1952,7 +1972,9 @@ u32 sceIoDread(int id, u32 dirent_addr) {
|
||||
// d_private is pointing to an area of unknown size
|
||||
// - [0..12] "8.3" file name (null-terminated), could be empty.
|
||||
// - [13..???] long file name (null-terminated)
|
||||
strncpy((char*)Memory::GetPointer(entry->d_private + 13), (const char*)entry->d_name, ARRAY_SIZE(entry->d_name));
|
||||
|
||||
// Hm, so currently we don't write the short name at all to d_private? TODO
|
||||
strcpy_limit((char*)Memory::GetPointer(entry->d_private + 13), (const char*)entry->d_name, ARRAY_SIZE(entry->d_name));
|
||||
}
|
||||
else {
|
||||
// d_private is pointing to an area of total size 1044
|
||||
@@ -1960,8 +1982,9 @@ u32 sceIoDread(int id, u32 dirent_addr) {
|
||||
// - [4..19] "8.3" file name (null-terminated), could be empty.
|
||||
// - [20..???] long file name (null-terminated)
|
||||
auto size = Memory::Read_U32(entry->d_private);
|
||||
// Hm, so currently we don't write the short name at all to d_private? TODO
|
||||
if (size >= 1044) {
|
||||
strncpy((char*)Memory::GetPointer(entry->d_private + 20), (const char*)entry->d_name, ARRAY_SIZE(entry->d_name));
|
||||
strcpy_limit((char*)Memory::GetPointer(entry->d_private + 20), (const char*)entry->d_name, ARRAY_SIZE(entry->d_name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user