static err_t OpenDir(filestream* p,const tchar_t* URL,int UNUSED_PARAM(Flags)) { if (p->FindDir>=0) { fileXioDclose(p->FindDir); p->FindDir=-1; } if (!URL[0]) { p->DevNo = 0; return ERR_NONE; } p->DevNo = -1; p->FindDir = fileXioDopen(URL); if (p->FindDir<0) { int fd = fileXioOpen(URL,O_RDONLY,0); if (fd >= 0) { fileXioClose(fd); return ERR_NOT_DIRECTORY; } else return ERR_FILE_NOT_FOUND; } tcscpy_s(p->DirPath,TSIZEOF(p->DirPath),URL); AddPathDelimiter(p->DirPath,TSIZEOF(p->DirPath)); return ERR_NONE; }
static void hddUpdateInfo() { iox_dirent_t infoDirEnt; int rv; int hddFd, hddUsed = 0; hddSize = fileXioDevctl("hdd0:", HDDCTL_TOTAL_SECTORS, NULL, 0, NULL, 0) * 512 / 1024 / 1024; /* This seems to give in-accurate results fileXioDevctl("hdd0:", HDDCTL_FREE_SECTORS, NULL, 0, &rv, 4); hddFree = rv * 512 / 1024 / 1024; */ hddFd = fileXioDopen("hdd0:"); if(hddFd < 0) // For when a HDD is not connected! return; rv = fileXioDread(hddFd, &infoDirEnt); while(rv > 0) { if(infoDirEnt.stat.mode != FS_TYPE_EMPTY) hddUsed += infoDirEnt.stat.size * 512 / 1024 / 1024; rv = fileXioDread(hddFd, &infoDirEnt); } fileXioDclose(hddFd); hddFree = hddSize - hddUsed; hddMaxPartitionSize = fileXioDevctl("hdd0:", HDDCTL_MAX_SECTORS, NULL, 0, NULL, 0) * 512 / 1024 / 1024; hddStatusCurrent = 1; }
int AsyncFio::dopen(const char *name) { int res; WaitSema(_ioSema); checkSync(); fileXioDopen(name); fileXioWaitAsync(FXIO_WAIT, &res); SignalSema(_ioSema); return res; }
void list_path(char *path, list_t *list) { int fd; int n = 0; iox_dirent_t buf; if(!strncmp(path,"cdfs:",5)) { CDVD_FlushCache(); } // Add fake .. directory entry add_reg_entry(list->entries, "..", n++); // Try to open the path if((fd=fileXioDopen(path)) < 0) { list->num = n; return; } else { // Add directories first while(fileXioDread(fd, &buf) > 0) { if(buf.stat.mode & FIO_S_IFDIR && (!strcmp(buf.name,".") || !strcmp(buf.name,".."))) continue; if(buf.stat.mode & FIO_S_IFDIR) { add_dir_entry(list->entries, buf.name, n++); } if (buf.stat.mode & FIO_S_IFREG) { add_reg_entry(list->entries, buf.name, n++); } // Prevent overflowing the list if (n >= list->size) { break; } } list->num = n; fileXioDclose(fd); } }
int AsyncFio::dopen(const char *name) { int res; WaitSema(_ioSema); checkSync(); fileXioDopen(name); fileXioWaitAsync(FXIO_WAIT, &res); SignalSema(_ioSema); dbg_printf("FIO: dopen(%s) => %d\n", name, res); return res; }
void list_partitions(list_t *list) { iox_dirent_t hddEnt; int hddFd; int n = 1; printf("listing partitions\n"); if((hddFd=fileXioDopen("hdd0:")) < 0) { list->num = n; return; } while(fileXioDread(hddFd, &hddEnt) > 0) { if((hddEnt.stat.attr != ATTR_MAIN_PARTITION) || (hddEnt.stat.mode != FS_TYPE_PFS)) continue; //Patch this to see if new CB versions use valid PFS format //NB: All CodeBreaker versions up to v9.3 use invalid formats if(!strncmp(hddEnt.name, "PP.",3)) { int len = strlen(hddEnt.name); if(!strcmp(hddEnt.name+len-4, ".PCB")) continue; } /* if(!strncmp(hddEnt.name, "__", 2)) { if(strcmp(hddEnt.name, "__boot")) continue; if(strcmp(hddEnt.name, "__net")) continue; if(strcmp(hddEnt.name, "__system")) continue; if(strcmp(hddEnt.name, "__sysconf")) continue; if(strcmp(hddEnt.name, "__common")) continue; } */ add_reg_entry(list->entries,hddEnt.name, n++); } fileXioDclose(hddFd); list->num = n; }
bool_t PathIsFolder(nodecontext *p,const tchar_t* Path) { // not all file systems supports fileXioGetstat if (tcsnicmp(Path,T("cdrom"),5)!=0) { int fd = fileXioDopen(Path); if (fd >= 0) { fileXioDclose(fd); return 1; } } return 0; }
/**************************************************************************** * This function opens the directory in the folder struct. It should only * * be called 1 time. It has no effect for CD directories. * ****************************************************************************/ int openDirectory(char *dir, int media) { strcpy(folder.directory, dir); switch (media) { case 0: { folder.iDir = fileXioDopen(dir); if (folder.iDir < 0) return -1; return 0; } case 1: { return 0; } } return 0; }
void Ps2FilesystemNode::doverify(void) { PS2Device medium; int fd; if (_verified) return; _verified = true; dbg_printf(" verify: %s -> ", _path.c_str()); #if 0 if (_path.empty()) { dbg_printf("PlayStation 2 Root !\n"); _verified = true; return; } if (_path.lastChar() == ':') { dbg_printf("Dev: %s\n", _path.c_str()); _verified = true; return; } #endif if (_path[3] != ':' && _path[4] != ':') { dbg_printf("relative path !\n"); _isHere = false; _isDirectory = false; return; } medium = _getDev(_path); if (medium == ERR_DEV) { _isHere = false; _isDirectory = false; return; } switch (medium) { #if 0 case HD_DEV: /*stat*/ case USB_DEV: iox_stat_t stat; fileXioGetStat(_path.c_str(), &stat); fileXioWaitAsync(FXIO_WAIT, &fd); if (!fd) { dbg_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); dbg_printf("_path = %s -- fio.open -> %d\n", _path.c_str(), fd); if (fd >=0) { fio.close(fd); dbg_printf(" yes [open]\n"); _isHere = true; if (medium==MC_DEV && _path.lastChar()=='/') _isDirectory = true; else _isDirectory = false; return; } fd = fio.dopen(_path.c_str()); if (fd >=0) { fio.dclose(fd); dbg_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; dbg_printf(" no\n"); return; }
static err_t EnumDir(filestream* p,const tchar_t* Exts,bool_t ExtFilter,streamdir* Item) { iox_dirent_t Dirent; Item->FileName[0] = 0; Item->DisplayName[0] = 0; if (p->DevNo>=0) { static const tchar_t* const Devices[] = { "mass:", //"cdrom:", //driver doesn't support directory listing "hdd:", //"host:", //driver doesn't support directory listing "cdda:", "cdfs:", "smb:", NULL, }; for (;!Item->FileName[0];++p->DevNo) { int fd; const tchar_t* URL = Devices[p->DevNo]; if (!URL) break; fd = fileXioDopen(URL); if (fd>=0) { fileXioDclose(fd); tcscpy_s(Item->FileName,TSIZEOF(Item->FileName), URL); Item->ModifiedDate = INVALID_DATETIME_T; Item->Type = FTYPE_DIR; Item->Size = INVALID_FILEPOS_T; } } } else { if (p->FindDir<0) return ERR_END_OF_FILE; while (!Item->FileName[0]) { if (fileXioDread(p->FindDir,&Dirent)<=0) break; if (Dirent.name[0]=='.') // skip unix/mac hidden files continue; tcscpy_s(Item->FileName,TSIZEOF(Item->FileName), Dirent.name); Item->ModifiedDate = PS2ToDateTime(Dirent.stat.mtime); if (FIO_S_ISDIR(Dirent.stat.mode)) { Item->Type = FTYPE_DIR; Item->Size = INVALID_FILEPOS_T; } else { Item->Size = Dirent.stat.size; Item->Type = CheckExts(Item->FileName,Exts); if (!Item->Type && ExtFilter) Item->FileName[0] = 0; // skip } } } if (!Item->FileName[0]) { if (p->FindDir>=0) { fileXioDclose(p->FindDir); p->FindDir = -1; } return ERR_END_OF_FILE; } return ERR_NONE; }
int DirGetContents( const char *path, const char *filter, fileInfo_t *fileInfo, int maxItems ) { int c, i; char *ptr; int numRead; int index = 0; if( !path || !fileInfo || !maxItems ) return -1; if( (ptr = strchr( path, '/' )) == NULL ) { printf("DirGetContents : Invalid Path (ptr = NULL)\n"); return -1; } c = ptr - path; // try to read in dir from cd/dvd if( !strncmp( path, "cdfs:/", c ) ) { // just make sure we are initialized CD_Init(); struct TocEntry *tocEntries = (struct TocEntry*) malloc( sizeof(struct TocEntry) * maxItems ); if( !tocEntries ) return -1; CDVD_FlushCache(); numRead = CDVD_GetDir( ptr, NULL, CDVD_GET_FILES_AND_DIRS, tocEntries, maxItems, NULL ); CDVD_Stop(); index = 0; ptr = NULL; if( filter ) ptr = (char*) malloc( strlen(filter) + 1 ); for( i = 0; i < numRead; i++ ) { if( index >= maxItems ) break; if( !strcmp( tocEntries[i].filename, ".." ) || !strcmp( tocEntries[i].filename, "." ) ) continue; // check for filters c = 1; if( filter && !(tocEntries[i].fileProperties & FLAG_DIRECTORY) ) { strcpy( ptr, filter ); c = 0; char *token = strtok( ptr, " " ); while( token ) { // found matching extension if( CmpFileExtension( tocEntries[i].filename, token ) ) { c = 1; break; } token = strtok( NULL, " " ); } } if( c == 1 ) { strncpy( fileInfo[index].name, tocEntries[i].filename, sizeof(fileInfo[index].name) ); fileInfo[index].size = tocEntries[i].fileSize; fileInfo[index].flags = tocEntries[i].fileProperties; index++; } } if( ptr ) free(ptr); free(tocEntries); } else if( !strncmp( path, "pfs", 3 ) ) { // try to read in dir from hdd int hDir = fileXioDopen( path ); int nRet; iox_dirent_t dirEntry; if( hDir < 0 ) return -1; index = 0; ptr = NULL; if( filter ) ptr = (char*) malloc( strlen(filter) + 1 ); do { if( !(nRet = fileXioDread( hDir, &dirEntry )) ) break; if(!strcmp( dirEntry.name, "." ) || !strcmp( dirEntry.name, "..")) continue; if( index >= maxItems ) break; if( FIO_S_ISDIR(dirEntry.stat.mode) ) fileInfo[index].flags = FLAG_DIRECTORY; else fileInfo[index].flags = 0; // check for filters c = 1; if( filter && !(fileInfo[index].flags & FLAG_DIRECTORY) ) { strcpy( ptr, filter ); c = 0; char *token = strtok( ptr, " " ); while( token ) { // found matching extension if( CmpFileExtension( dirEntry.name, token ) ) { c = 1; break; } token = strtok( NULL, " " ); } } if( c == 1 ) { strncpy( fileInfo[index].name, dirEntry.name, sizeof(fileInfo[index].name) ); fileInfo[index].size = dirEntry.stat.size; index++; } } while( nRet > 0 ); if( ptr ) free(ptr); fileXioDclose( hDir ); } else if( !strncmp( path, "mc0:/", c ) || !strncmp( path, "mc1:/", c ) ) { // try to read in dir from memory card int nPort; char mcPath[256]; mcTable mcEntries[MAX_DIR_FILES] __attribute__((aligned(64))); if( !strncmp( path, "mc0:/", c ) ) nPort = 0; else nPort = 1; strcpy( mcPath, ptr ); strcat( mcPath, "*" ); mcGetDir( nPort, 0, mcPath, 0, MAX_DIR_FILES, mcEntries ); mcSync( 0, NULL, &numRead ); index = 0; ptr = NULL; if( filter ) ptr = (char*) malloc( strlen(filter) + 1 ); for( i = 0; i < numRead; i++ ) { if( index >= maxItems ) break; if( !strcmp( mcEntries[i].name, "." ) || !strcmp( mcEntries[i].name, "..") ) continue; if( mcEntries[i].attrFile & MC_ATTR_SUBDIR ) fileInfo[index].flags = FLAG_DIRECTORY; else fileInfo[index].flags = 0; // check for filters c = 1; if( filter && !(mcEntries[i].attrFile & MC_ATTR_SUBDIR) ) { strcpy( ptr, filter ); c = 0; char *token = strtok( ptr, " " ); while( token ) { // found matching extension if( CmpFileExtension( mcEntries[i].name, token ) ) { c = 1; break; } token = strtok( NULL, " " ); } } if( c == 1 ) { strncpy( fileInfo[index].name, mcEntries[i].name, sizeof(fileInfo[index].name) ); fileInfo[index].size = mcEntries[i].fileSizeByte; index++; } } if( ptr ) free(ptr); } else if( !strncmp( path, "mass:/", c ) ) { // try to read in dir from USB device int nRet; fat_dir_record dirEntry; // returns number of entries in directory nRet = usb_mass_getFirstDirentry( ptr, &dirEntry ); index = 0; ptr = NULL; if( filter ) ptr = (char*) malloc( strlen(filter) + 1 ); // loop through all entries in directory while( nRet > 0 ) { if(!strcmp( dirEntry.name, "." ) || !strcmp( dirEntry.name, "..")) { nRet = usb_mass_getNextDirentry(&dirEntry); continue; } // ignore volume label if( dirEntry.attr & USB_VOLUME ) { nRet = usb_mass_getNextDirentry(&dirEntry); continue; } if( index >= maxItems ) break; if( dirEntry.attr & USB_DIRECTORY ) fileInfo[index].flags = FLAG_DIRECTORY; else fileInfo[index].flags = 0; // check for filters c = 1; if( filter && !(fileInfo[index].flags & FLAG_DIRECTORY) ) { strcpy( ptr, filter ); c = 0; char *token = strtok( ptr, " " ); while( token ) { // found matching extension if( CmpFileExtension( dirEntry.name, token ) ) { c = 1; break; } token = strtok( NULL, " " ); } } if( c == 1 ) { strncpy( fileInfo[index].name, dirEntry.name, sizeof(fileInfo[index].name) ); fileInfo[index].size = dirEntry.size; index++; } nRet = usb_mass_getNextDirentry( &dirEntry ); } if( ptr ) free(ptr); } else if( !strncmp( path, "smb", 3 ) ) { // read from a samba share int hDir = smbc_opendir( path ); const struct smbc_dirent *dirEntry; if( hDir < 0 ) return -1; index = 0; ptr = NULL; if( filter ) ptr = (char*) malloc( strlen(filter) + 1 ); while( (dirEntry = smbc_readdir( hDir )) != NULL ) { if(!strcmp( dirEntry->name, "." ) || !strcmp( dirEntry->name, "..")) continue; if( index >= maxItems ) break; if( dirEntry->smbc_type == SMBC_DIR ) fileInfo[index].flags = FLAG_DIRECTORY; else fileInfo[index].flags = 0; // check for filters c = 1; if( filter && !(fileInfo[index].flags & FLAG_DIRECTORY) ) { strcpy( ptr, filter ); c = 0; char *token = strtok( ptr, " " ); while( token ) { // found matching extension if( CmpFileExtension( dirEntry->name, token ) ) { c = 1; break; } token = strtok( NULL, " " ); } } if( c == 1 ) { strncpy( fileInfo[index].name, dirEntry->name, sizeof(fileInfo[index].name) ); fileInfo[index].size = 0; // fixme index++; } }; if( ptr ) free(ptr); smbc_closedir( hDir ); } return index; }
int hddGetFilesystemList(t_hddFilesystem hddFs[], int maxEntries) { iox_dirent_t dirEnt; int count = 0; u32 size = 0; int hddFd; int rv; if(!hddStatusCurrent) hddUpdateInfo(); hddFd = fileXioDopen("hdd0:"); if(hddFd < 0) return hddFd; rv = fileXioDread(hddFd, &dirEnt); while((rv > 0) && (count < maxEntries)) { int i; int partitionFd; u32 zoneFree, zoneSize; // We only want to know about main partitions (non-empty ones at that :P) if((dirEnt.stat.attr & ATTR_SUB_PARTITION) || (dirEnt.stat.mode == FS_TYPE_EMPTY)) { rv = fileXioDread(hddFd, &dirEnt); continue; } memset(&hddFs[count], 0, sizeof(t_hddFilesystem)); sprintf(hddFs[count].filename, "hdd0:%s", dirEnt.name); // Work out filesystem type if((dirEnt.name[0] == '_') && (dirEnt.name[1] == '_')) { hddFs[count].fileSystemGroup = FS_GROUP_SYSTEM; strcpy(hddFs[count].name, &dirEnt.name[2]); } else if(dirEnt.name[0] == FS_COMMON_PREFIX) { hddFs[count].fileSystemGroup = FS_GROUP_COMMON; strcpy(hddFs[count].name, &dirEnt.name[1]); } else { hddFs[count].fileSystemGroup = FS_GROUP_APPLICATION; strcpy(hddFs[count].name, dirEnt.name); } #ifdef _OMIT_SYSTEM_PARTITION if((hddFs[count].fileSystemGroup == FS_GROUP_SYSTEM) && strcmp(hddFs[count].name, "boot")) { rv = fileXioDread(hddFd, &dirEnt); continue; } #endif #ifdef DEBUG printf("> Filename: %s\n> Name: %s\n> Type: %d\n", hddFs[count].filename, hddFs[count].name, hddFs[count].fileSystemGroup); #endif // Calculate filesystem size partitionFd = fileXioOpen(hddFs[count].filename, O_RDONLY, 0); // If we failed to open the partition, then a password is probably set // (usually this means we have tried to access a game partition). We // dont want to return un-accessible game partitions in the filesystem list.. if(partitionFd < 0) { rv = fileXioDread(hddFd, &dirEnt); continue; } for(i = 0, size = 0; i < dirEnt.stat.private_0 + 1; i++) { rv = fileXioIoctl2(partitionFd, HDDIO_GETSIZE, &i, 4, NULL, 0); size += rv * 512 / 1024 / 1024; } fileXioClose(partitionFd); hddFs[count].size = size; // Get filesystem free space & format status hddFs[count].freeSpace = 0; hddFs[count].formatted = 0; if(dirEnt.stat.mode == FS_TYPE_PFS) { rv = fileXioMount("pfs0:", hddFs[count].filename, FIO_MT_RDONLY); if(rv == 0) { zoneFree = fileXioDevctl("pfs0:", PFSCTL_GET_ZONE_FREE, NULL, 0, NULL, 0); zoneSize = fileXioDevctl("pfs0:", PFSCTL_GET_ZONE_SIZE, NULL, 0, NULL, 0); hddFs[count].freeSpace = zoneFree * zoneSize / 1024 / 1024; hddFs[count].formatted = 1; fileXioUmount("pfs0:"); } } #ifdef DEBUG printf("> Formatted: %d\n> Size: %d\n> Free: %d\n", hddFs[count].formatted, (int)hddFs[count].size, (int)hddFs[count].freeSpace); #endif count++; rv = fileXioDread(hddFd, &dirEnt); } rv = fileXioDclose(hddFd); return count; }
/**************************************************************************** * This function changes the directory in the folder struct to a new * * directory. It has no effect for CD directories. * ****************************************************************************/ int changeDirectory(char *dir, int media) { int len, i, k=0; if (strcmp(dir, "..") == 0) //prev folder { len = strlen(folder.directory); k = 0; for (i=len-2; i >= 0; i--) { if (folder.directory[i] == '/') { k = 1; break; } } if (k == 1) { folder.directory[i+1] = 0; } } else if (strcmp(dir, ".") == 0) //current folder { return 0; } else { k = dir[4]; dir[4] = 0; if (strcmp(dir, "pfs0") == 0) { dir[4] = k; strcpy(folder.directory, dir); } else if (strcmp(dir, "cdfs") == 0) { dir[4] = k; strcpy(folder.directory, dir); } else { dir[4] = k; strcat(folder.directory, dir); strcat(folder.directory, "/"); } } printf("Directory is %s\n", folder.directory); switch (media) { case 0: { fileXioDclose(folder.iDir); fileXioChdir(folder.directory); folder.iDir = fileXioDopen(folder.directory); return 1; } case 1: { return 1; fioDclose(folder.iDir); folder.iDir = fioDopen(folder.directory); } } return 0; }