diff options
Diffstat (limited to 'backends/fs/ps2/ps2-fs.cpp')
-rw-r--r-- | backends/fs/ps2/ps2-fs.cpp | 413 |
1 files changed, 288 insertions, 125 deletions
diff --git a/backends/fs/ps2/ps2-fs.cpp b/backends/fs/ps2/ps2-fs.cpp index a8dcb4d2bb..57bdc8620f 100644 --- a/backends/fs/ps2/ps2-fs.cpp +++ b/backends/fs/ps2/ps2-fs.cpp @@ -33,6 +33,10 @@ #include "backends/platform/ps2/systemps2.h" #include "backends/platform/ps2/ps2debug.h" +#include <fileXio_rpc.h> + +#include "ps2temp.h" + #define DEFAULT_MODE (FIO_S_IRUSR | FIO_S_IWUSR | FIO_S_IRGRP | FIO_S_IWGRP | FIO_S_IROTH | FIO_S_IWOTH) extern AsyncFio fio; @@ -52,10 +56,12 @@ protected: Common::String _path; bool _isDirectory; bool _isRoot; + bool _isHere; + bool _verified; private: - char *getDeviceDescription(const char *path) const; - bool getDirectoryFlag(const char *path); + char *getDeviceDescription() const; + void doverify(); public: /** @@ -76,23 +82,28 @@ public: */ Ps2FilesystemNode(const Ps2FilesystemNode *node); - virtual bool exists(void) const; - virtual Common::String getDisplayName() const { return _displayName; } virtual Common::String getName() const { return _displayName; } virtual Common::String getPath() const { return _path; } + virtual bool exists() const { + // printf("%s : is %d\n", _path.c_str(), _isHere); + return _isHere; + } + virtual bool isDirectory() const { + // printf("%s : dir %d\n", _path.c_str(), _isDirectory); return _isDirectory; } virtual bool isReadable() const { - return exists(); + return _isHere; } virtual bool isWritable() const { - // The only writable device on the ps2 is the memory card - return false; + if (strncmp(_path.c_str(), "cdfs", 4)==0) + return false; + return true; // exists(); // creating ? } virtual AbstractFSNode *clone() const { return new Ps2FilesystemNode(this); } @@ -100,60 +111,110 @@ public: virtual bool getChildren(AbstractFSList &list, ListMode mode, bool hidden) const; virtual AbstractFSNode *getParent() const; - virtual Common::SeekableReadStream *createReadStream(); - virtual Common::WriteStream *createWriteStream(); + virtual Common::SeekableReadStream *openForReading(); + virtual Common::WriteStream *openForWriting(); + + int getDev() { return 0; }; }; +const char *_lastPathComponent(const Common::String &str) { + if (str.empty()) + return ""; + + const char *start = str.c_str(); + const char *cur = start + str.size() - 2; + + while (cur >= start && *cur != '/' && *cur != ':') { + --cur; + } + + cur++; + + // printf("lastPathComponent path=%s token=%s\n", start, cur); + + return cur; +} + Ps2FilesystemNode::Ps2FilesystemNode() { + printf("NEW FSNODE()\n"); + + _isHere = true; _isDirectory = true; _isRoot = true; - _displayName = "PlayStation 2"; + _verified = false; + _displayName = Common::String("PlayStation 2"); _path = ""; } Ps2FilesystemNode::Ps2FilesystemNode(const Common::String &path) { + printf("NEW FSNODE(%s)\n", path.c_str()); + _path = path; - _isDirectory = true; - if (strcmp(path.c_str(), "") == 0) { + + if (path.empty()) { + _isHere = true; + _isDirectory = true; /* root is always a dir */ _isRoot = true; _displayName = Common::String("PlayStation 2"); + _verified = true; + } else if (path.lastChar() == ':') { + _isHere = true; + _isDirectory = true; /* devs are always a dir */ + _isRoot = false; + _displayName = getDeviceDescription(); + _verified = true; } else { + _verified = false; + doverify(); + if (!_isHere) + return; + + _displayName = _lastPathComponent(_path); + + if (_isDirectory && _path.lastChar() != '/') + _path+= '/'; + _isRoot = false; - const char *dsplName = NULL, *pos = path.c_str(); - while (*pos) - if (*pos++ == '/') - dsplName = pos; - if (dsplName) - _displayName = Common::String(dsplName); - else - _displayName = getDeviceDescription(path.c_str()); } } Ps2FilesystemNode::Ps2FilesystemNode(const Common::String &path, bool verify) { + printf("NEW FSNODE(%s, %d)\n", path.c_str(), verify); + _path = path; - if (strcmp(path.c_str(), "") == 0) { - _isRoot = true; /* root is always a dir*/ + if (path.empty()) { + _isHere = true; + _isDirectory = true; /* root is always a dir */ + _isRoot = true; _displayName = Common::String("PlayStation 2"); - _isDirectory = true; - } else { + _verified = true; + } else if (path.lastChar() == ':') { + _isHere = true; + _isDirectory = true; /* devs are always a dir */ _isRoot = false; - const char *dsplName = NULL, *pos = path.c_str(); - while (*pos) - if (*pos++ == '/') - dsplName = pos; - - if (dsplName) { - _displayName = Common::String(dsplName); - if (verify) - _isDirectory = getDirectoryFlag(path.c_str()); - else - _isDirectory = false; + _displayName = getDeviceDescription(); + _verified = true; + } else { + _verified = false; + if (verify) { + doverify(); + + if (!_isHere) + return; + } else { - _displayName = getDeviceDescription(path.c_str()); - _isDirectory = true; /* devices are always dir */ + _verified = false; + _isDirectory = false; + _isHere = false; // true } + + _displayName = _lastPathComponent(_path); + + if (_isDirectory && _path.lastChar() != '/') + _path+= '/'; + + _isRoot = false; } } @@ -162,61 +223,149 @@ Ps2FilesystemNode::Ps2FilesystemNode(const Ps2FilesystemNode *node) { _isDirectory = node->_isDirectory; _path = node->_path; _isRoot = node->_isRoot; + _isHere = node->_isHere; + _verified = node->_verified; } -bool Ps2FilesystemNode::exists(void) const { +void Ps2FilesystemNode::doverify(void) { + PS2Device medium; + int fd; - dbg_printf("Ps2FilesystemNode::exists: path \"%s\": ", _path.c_str()); + if (_verified) + return; - if (_path[4] != ':') { // don't bother for relative path... they always fail on PS2! - dbg_printf("NO, relative path\n"); - return false; + _verified = true; + + printf(" verify: %s -> ", _path.c_str()); + +#if 0 + if (_path.empty()) { + printf("PlayStation 2 Root !\n"); + _verified = true; + return; } - if (_path[0] == 'h') { // bypass host - dbg_printf("NO, host device ignored\n"); - return false; + if (_path.lastChar() == ':') { + printf("Dev: %s\n", _path.c_str()); + _verified = true; + return; } +#endif - int fd = fio.open(_path.c_str(), O_RDONLY); - if (fd == -EISDIR) { - dbg_printf("YES, directory\n"); - return true; - } else if (fd >= 0) { - dbg_printf("YES, file\n"); - fio.close(fd); - return true; + if (_path[3] != ':' && _path[4] != ':') { + printf("relative path !\n"); + _isHere = false; + _isDirectory = false; + return; } - printf("NO, not found\n"); - return false; -} + medium = _getDev(_path); + if (medium == ERR_DEV) { + _isHere = false; + _isDirectory = false; + return; + } -bool Ps2FilesystemNode::getDirectoryFlag(const char *path) { - if (strncmp(path, "host:", 5) == 0) - return true; // Can't get listings from host: right now + switch (medium) { +#if 0 + case HD_DEV: /*stat*/ + case USB_DEV: + iox_stat_t stat; - int fd = fio.open(_path.c_str(), O_RDONLY); + fileXioGetStat(_path.c_str(), &stat); + fileXioWaitAsync(FXIO_WAIT, &fd); - if (fd == -EISDIR) { - dbg_printf(" romeo : new node [ %s ] is a dir\n", path); - return true; - } else if (fd >=0) { - dbg_printf(" romeo : new node [ %s ] is -not- a dir (%d)\n", path, fd); + if (!fd) { + printf(" yes [stat]\n"); + return true; + } + break; +#endif + + case CD_DEV: /*no stat*/ + case HD_DEV: + case USB_DEV: + case HOST_DEV: + case MC_DEV: +#if 1 + fd = fio.open(_path.c_str(), O_RDONLY); + + printf("_path = %s -- fio.open -> %d\n", _path.c_str(), fd); + + if (fd >=0) { fio.close(fd); - } else - dbg_printf(" romeo : new node [ %s ] is -not- (%d)\n", path, fd); + printf(" yes [open]\n"); + _isHere = true; + if (medium==MC_DEV && _path.lastChar()=='/') + _isDirectory = true; + else + _isDirectory = false; + return; + } - return false; + fd = fio.dopen(_path.c_str()); + if (fd >=0) { + fio.dclose(fd); + printf(" yes [dopen]\n"); + _isHere = true; + _isDirectory = true; + return; + } + +#else + fileXioOpen(_path.c_str(), O_RDONLY, DEFAULT_MODE); + fileXioWaitAsync(FXIO_WAIT, &fd); + if (fd>=0) { + fileXioClose(fd); + fileXioWaitAsync(FXIO_WAIT, &fd); + return true; + } + + fileXioDopen(_path.c_str()); + fileXioWaitAsync(FXIO_WAIT, &fd); + if (fd>=0) { + fileXioDclose(fd); + fileXioWaitAsync(FXIO_WAIT, &fd); + return true; + } +#endif + break; + case ERR_DEV: + _isHere = false; + _isDirectory = false; + break; + } + + _isHere = false; + _isDirectory = false; + + printf(" no\n"); + return; } AbstractFSNode *Ps2FilesystemNode::getChild(const Common::String &n) const { + + printf("getChild : %s\n", n.c_str()); + if (!_isDirectory) return NULL; - char listDir[256]; - sprintf(listDir, "%s/", _path.c_str()); - int fd = fio.dopen(listDir); + if (_isRoot) { + if (n.lastChar() == ':') + return new Ps2FilesystemNode(n); + else + return NULL; + } + + return new Ps2FilesystemNode(_path+n, 1); + +/* + int fd; + + if (_path == "pfs0:") + fd = fio.dopen("pfs0:/"); + else + fd = fio.dopen(_path.c_str()); if (fd >= 0) { iox_dirent_t dirent; @@ -225,15 +374,18 @@ AbstractFSNode *Ps2FilesystemNode::getChild(const Common::String &n) const { if (strcmp(n.c_str(), dirent.name) == 0) { Ps2FilesystemNode *dirEntry = new Ps2FilesystemNode(); + dirEntry->_isHere = true; dirEntry->_isDirectory = (bool)(dirent.stat.mode & FIO_S_IFDIR); dirEntry->_isRoot = false; dirEntry->_path = _path; - dirEntry->_path += "/"; dirEntry->_path += dirent.name; - + if (dirEntry->_isDirectory && dirEntry->_path.lastChar() != '/') + dirEntry->_path += '/'; dirEntry->_displayName = dirent.name; + dirEntry->_verified = true; + fio.dclose(fd); return dirEntry; } @@ -242,109 +394,120 @@ AbstractFSNode *Ps2FilesystemNode::getChild(const Common::String &n) const { } return NULL; +*/ } bool Ps2FilesystemNode::getChildren(AbstractFSList &list, ListMode mode, bool hidden) const { //TODO: honor the hidden flag + // printf("getChildren\n"); + if (!_isDirectory) return false; if (_isRoot) { - Ps2FilesystemNode dirEntry; - dirEntry._isDirectory = true; - dirEntry._isRoot = false; - dirEntry._path = "cdfs:"; - dirEntry._displayName = getDeviceDescription(dirEntry._path.c_str()); - list.push_back(new Ps2FilesystemNode(&dirEntry)); - - if (g_systemPs2->hddPresent()) { - dirEntry._path = "pfs0:"; - dirEntry._displayName = getDeviceDescription(dirEntry._path.c_str()); - list.push_back(new Ps2FilesystemNode(&dirEntry)); - } + list.push_back(new Ps2FilesystemNode("cdfs:")); + + if (g_systemPs2->hddPresent()) + list.push_back(new Ps2FilesystemNode("pfs0:")); + + if (g_systemPs2->usbMassPresent()) + list.push_back(new Ps2FilesystemNode("mass:")); + + if (g_systemPs2->getBootDevice()==HOST_DEV || g_systemPs2->netPresent()) + list.push_back(new Ps2FilesystemNode("host:")); + + if (g_systemPs2->mcPresent()) + list.push_back(new Ps2FilesystemNode("mc0:")); - if (g_systemPs2->usbMassPresent()) { - dirEntry._path = "mass:"; - dirEntry._displayName = getDeviceDescription(dirEntry._path.c_str()); - list.push_back(new Ps2FilesystemNode(&dirEntry)); - } return true; } else { - char listDir[256]; int fd; - if (_path.lastChar() == '/' /* || _path.lastChar() == ':'*/) + if (_path == "pfs0:") + fd = fio.dopen("pfs0:/"); + else fd = fio.dopen(_path.c_str()); - else { - sprintf(listDir, "%s/", _path.c_str()); - fd = fio.dopen(listDir); - } + + // printf("dopen = %d\n", fd); if (fd >= 0) { iox_dirent_t dirent; Ps2FilesystemNode dirEntry; int dreadRes; while ((dreadRes = fio.dread(fd, &dirent)) > 0) { + if (dirent.name[0] == '.') continue; // ignore '.' and '..' - if (((mode == Common::FSNode::kListDirectoriesOnly) && (dirent.stat.mode & FIO_S_IFDIR)) || - ((mode == Common::FSNode::kListFilesOnly) && !(dirent.stat.mode & FIO_S_IFDIR)) || - (mode == Common::FSNode::kListAll)) { + if ( (mode == Common::FSNode::kListAll) || + + ((mode == Common::FSNode::kListDirectoriesOnly) && + (dirent.stat.mode & FIO_S_IFDIR)) || + + ((mode == Common::FSNode::kListFilesOnly) && + !(dirent.stat.mode & FIO_S_IFDIR)) ) { + + dirEntry._isHere = true; dirEntry._isDirectory = (bool)(dirent.stat.mode & FIO_S_IFDIR); dirEntry._isRoot = false; dirEntry._path = _path; - if (_path.lastChar() != '/') - dirEntry._path += "/"; dirEntry._path += dirent.name; - + if (dirEntry._isDirectory && dirEntry._path.lastChar() != '/') + dirEntry._path += '/'; dirEntry._displayName = dirent.name; + dirEntry._verified = true; + list.push_back(new Ps2FilesystemNode(&dirEntry)); } } fio.dclose(fd); return true; - } else - return false; + } } + return false; } AbstractFSNode *Ps2FilesystemNode::getParent() const { + // printf("Ps2FilesystemNode::getParent : path = %s\n", _path.c_str()); + if (_isRoot) - return new Ps2FilesystemNode(this); + return new Ps2FilesystemNode(this); // FIXME : 0 ??? - const char *slash = NULL; - const char *cnt = _path.c_str(); + if (_path.lastChar() == ':') // devs + return new Ps2FilesystemNode(); // N: default is root - while (*cnt) { - if (*cnt == '/') - slash = cnt; - cnt++; - } + const char *start = _path.c_str(); + const char *end = _lastPathComponent(_path); - if (slash) - return new Ps2FilesystemNode(Common::String(_path.c_str(), slash - _path.c_str())); - else - return new Ps2FilesystemNode(); -} + Common::String str(start, end - start); + // printf(" parent = %s\n", str.c_str()); + return new Ps2FilesystemNode(str, true); +} -char *Ps2FilesystemNode::getDeviceDescription(const char *path) const { - if (strncmp(path, "cdfs", 4) == 0) +char *Ps2FilesystemNode::getDeviceDescription() const { + if (strncmp(_path.c_str(), "cdfs", 4) == 0) return "DVD Drive"; - else if (strncmp(path, "mass", 4) == 0) - return "USB Mass Storage"; - else + else if (strncmp(_path.c_str(), "pfs0", 4) == 0) return "Harddisk"; + else if (strncmp(_path.c_str(), "mass", 4) == 0) + return "USB Mass Storage"; + else if (strncmp(_path.c_str(), "host", 4) == 0) + return "Host"; + else if (strncmp(_path.c_str(), "mc0", 3) == 0) + return "Memory Card"; + else + return "WTF ???"; } -Common::SeekableReadStream *Ps2FilesystemNode::createReadStream() { - return StdioStream::makeFromPath(getPath().c_str(), false); +Common::SeekableReadStream *Ps2FilesystemNode::openForReading() { + Common::SeekableReadStream *ss = StdioStream::makeFromPath(getPath().c_str(), false); + return ss; } -Common::WriteStream *Ps2FilesystemNode::createWriteStream() { +Common::WriteStream *Ps2FilesystemNode::openForWriting() { return StdioStream::makeFromPath(getPath().c_str(), true); } |