bool Ps2SaveFileManager::mcCheck(const char *path) { // Common::FSNode dir(Common::String(path), 1); // FIXED in gcc 3.4.x const Common::String str(path); Common::FSNode dir(str); // int res; printf("mcCheck\n"); if (!dir.exists()) { printf("! exist -> create : "); #ifdef __USE_LIBMC__ printf("%s\n", path+4); // WaitSema(_sema); mcSync(0, NULL, NULL); mcMkDir(0 /*port*/, 0 /*slot*/, path+4); mcSync(0, NULL, &res); printf("sync : %d\n", res); // SignalSema(_sema); #else printf("%s\n", path); fio.mkdir(path); #endif } // TODO: res; return true; }
int McAccess::size(int fd) { int res, size; WaitSema(_sema); mcSeek(fd, 0, SEEK_END); mcSync(0, NULL, &size); mcSeek(fd, 0, SEEK_SET); mcSync(0, NULL, &res); SignalSema(_sema); assert(res == 0); return size; }
mcIO::mcIO(int port, int maxEntries) { int type, free, format; int rv; #ifdef AIOMC_DEBUG printf("mcIO constructor.\n"); #endif this->port = port; mcEntries = NULL; // Make sure memory card was detected mcGetInfo(port, 0, &type, &free, &format); mcSync(MC_WAIT, NULL, &rv); if((rv < -1)) //|| !format //Since we're not using XMC format is always 0 { status = AIO_STATE_ERROR; return; } mcEntries = (mcTable *)memalign(64, sizeof(mcTable) * maxEntries); if(!mcEntries) printf("Failed to allocate memory!"); // TODO: remove when not used anymore sprintf(devname, "mc%d:", port); status = 0; }
int McAccess::close(int fd) { int res; WaitSema(_sema); mcClose(fd); mcSync(0, NULL, &res); SignalSema(_sema); return res; }
int McAccess::open(const char *name, int mode) { int res; WaitSema(_sema); mcOpen(_port, _slot, name, mode); mcSync(0, NULL, &res); SignalSema(_sema); return res; }
int McAccess::getInfo(int *type, int *free, int *format) { int res; WaitSema(_sema); mcGetInfo(_port, _slot, type, free, format); mcSync(0, NULL, &res); SignalSema(_sema); return res; }
int McAccess::getDir(const char *name, unsigned int mode, int max, void *dest) { int res; WaitSema(_sema); mcGetDir(_port, _slot, name, mode, max, (mcTable*)dest); mcSync(0, NULL, &res); SignalSema(_sema); return res; }
int McAccess::remove(const char *name) { int res; WaitSema(_sema); mcDelete(_port, _slot, name); mcSync(0, NULL, &res); SignalSema(_sema); return res; }
int McAccess::mkDir(const char *name) { int res; WaitSema(_sema); mcMkDir(_port, _slot, name); mcSync(0, NULL, &res); SignalSema(_sema); return res; }
int McAccess::write(int fd, const void *buf, int size) { int res; WaitSema(_sema); mcWrite(fd, buf, size); mcSync(0, NULL, &res); SignalSema(_sema); return res; }
int McAccess::read(int fd, void *buf, int size) { int res; WaitSema(_sema); mcRead(fd, buf, size); mcSync(0, NULL, &res); SignalSema(_sema); return res; }
// Hacked for PGEN - add a ".." to the top of the list if its not there already int mcIO::getdir(const char *name, const char *extensions, t_aioDent dentBuf[], int maxEnt) { char thisName[1024]; int numEntries; int i; int count = 0; #ifdef AIOMC_DEBUG printf("mcIO getdir - %s, maxEnt = %d\n", name, maxEnt); #endif if(!strcmp(name, "/")) strcpy(thisName, "/*"); else snprintf(thisName, 1024, "%s/*", name); mcGetDir(port, 0, thisName, 0, maxEnt, mcEntries); mcSync(MC_WAIT, NULL, &numEntries); if(numEntries < -1) return numEntries; // printf("mcIO getdir: got %d entries\n", numEntries); if(!strcmp(name, "/")) { strcpy(dentBuf[0].name, ".."); dentBuf[0].attrib = AIO_ATTRIB_DIR; dentBuf[0].size = 512; count++; } for(i = 0; (i < numEntries) && (count < maxEnt); i++) { // printf("mcEntries[%d].name = %s\n", i, mcEntries[i].name); if(strcmp((char *)mcEntries[i].name, ".")) { if( (tocEntryCompare((char *)mcEntries[i].name, extensions)) || (mcEntries[i].attrFile & MC_ATTR_SUBDIR) ) { strncpy(dentBuf[count].name, (char *)mcEntries[i].name, 256); dentBuf[count].name[255] = '\0'; // for safety dentBuf[count].attrib = 0; if(mcEntries[i].attrFile & MC_ATTR_SUBDIR) dentBuf[count].attrib |= AIO_ATTRIB_DIR; dentBuf[count].size = mcEntries[i].fileSizeByte; // printf("dentBuf[%d].name = %s\n", count, dentBuf[count].name); count++; } } } // printf("returning with %d entries!\n", count); return count; }
int mcIO::rename(const char *old, const char *newname) { int rv; #ifdef AIOMC_DEBUG printf("mcIO rename\n"); #endif mcRename(port, 0, old, newname); mcSync(MC_WAIT, NULL, &rv); return rv; }
int mcIO::lseek(int fd, int offset, int whence) { int rv; #ifdef AIOMC_DEBUG printf("mcIO lseek\n"); #endif mcSeek(fd, offset, whence); mcSync(MC_WAIT, NULL, &rv); return rv; }
int mcIO::read(int fd, unsigned char *buffer, int size) { int rv; #ifdef AIOMC_DEBUG // printf("mcIO read\n"); #endif mcRead(fd, buffer, size); mcSync(MC_WAIT, NULL, &rv); return rv; }
int mcIO::write(int fd, const unsigned char *buffer, int size) { int rv; #ifdef AIOMC_DEBUG printf("mcIO write\n"); #endif mcWrite(fd, buffer, size); mcSync(MC_WAIT, NULL, &rv); return rv; }
int mcIO::rmdir(const char *name) { int rv; #ifdef AIOMC_DEBUG printf("mcIO rmdir\n"); #endif mcDelete(port, 0, name); mcSync(MC_WAIT, NULL, &rv); return rv; }
int mcIO::close(int fd) { int rv; #ifdef AIOMC_DEBUG printf("mcIO close\n"); #endif mcClose(fd); mcSync(MC_WAIT, NULL, &rv); return rv; }
int mcIO::open(const char *name, int flags) { int rv; #ifdef AIOMC_DEBUG // printf("mcIO open\n"); #endif mcOpen(port, 0, name, flags); mcSync(MC_WAIT, NULL, &rv); return rv; }
int mcIO::freespace() { int type, free, format; int rv; mcGetInfo(port, 0, &type, &free, &format); mcSync(MC_WAIT, NULL, &rv); if(rv < -1) return rv; else return free; }
int mcIO::getstat(const char *name, t_aioDent *dent) { int rv; #ifdef AIOMC_DEBUG printf("mcIO getstat\n"); #endif mcGetDir(port, 0, name, 0, 1, mcEntries); mcSync(MC_WAIT, NULL, &rv); if(rv <= 0) return -1; strncpy(dent->name, (char *)mcEntries[0].name, 256); dent->name[255] = '\0'; // for safety dent->attrib = 0; if(mcEntries[0].attrFile & MC_ATTR_SUBDIR) dent->attrib |= AIO_ATTRIB_DIR; dent->size = mcEntries[0].fileSizeByte; return 0; }
/* ** ** [func] - fflush. ** [desc] - if the stream file is opened as read-only then returns 0. else ** if stream is a valid FILE stream and able to flush the stream ** file write buffer then returns 0. else returns EOF. ** [entr] - FILE *stream; the pointer to the FILE stream. ** [exit] - int; 0 if able to flush the write buffer or file is read-only. else EOF. ** [prec] - stream is a valid FILE pointer. ** [post] - the stream FILE stream write buffer is flushed. ** */ int fflush(FILE *stream) { int ret; switch(stream->type) { case STD_IOBUF_TYPE_GS: case STD_IOBUF_TYPE_SIO: case STD_IOBUF_TYPE_STDOUTHOST: /* stdout & stderr are never buffered. */ case STD_IOBUF_TYPE_CDROM: /* cd-rom files are read-only so no write buffer to flush. */ ret = 0; break; case STD_IOBUF_TYPE_MC: if (stream->flag & (_IOWRT | _IORW)) { /* flush memory card file write buffer. */ mcFlush(stream->fd); mcSync(0, NULL, &ret); if (ret != 0) { errno = (ret * -1); stream->flag |= _IOERR; ret = EOF; } } else ret = 0; break; case STD_IOBUF_TYPE_HOST: /* flush host file write buffer. */ if (stream->flag & (_IOWRT | _IORW)) ret = 0; else ret = 0; break; default: /* unknown/invalid I/O buffer type. */ errno = EBADFD; ret = EOF; } return (ret); }
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 createPSU(gameSave_t *save, device_t src) { FILE *psuFile, *mcFile; sceMcTblGetDir mcDir[64] __attribute__((aligned(64))); McFsEntry dir, file; fio_stat_t stat; char mcPath[100]; char psuPath[100]; char filePath[150]; char validName[32]; char *data; int numFiles = 0; int i, j, padding; int ret; float progress = 0.0; if(!save || !(src & (MC_SLOT_1|MC_SLOT_2))) return 0; memset(&dir, 0, sizeof(McFsEntry)); memset(&file, 0, sizeof(McFsEntry)); replaceIllegalChars(save->name, validName, '-'); rtrim(validName); snprintf(psuPath, 100, "%s%s.psu", flashDriveDevice, validName); if(fioGetstat(psuPath, &stat) == 0) { const char *items[] = {"Yes", "No"}; int choice = displayPromptMenu(items, 2, "Save already exists. Do you want to overwrite it?"); if(choice == 1) return 0; } psuFile = fopen(psuPath, "wb"); if(!psuFile) return 0; snprintf(mcPath, 100, "%s/*", strstr(save->path, ":") + 1); mcGetDir((src == MC_SLOT_1) ? 0 : 1, 0, mcPath, 0, 54, mcDir); mcSync(0, NULL, &ret); // Leave space for 3 directory entries (root, '.', and '..'). for(i = 0; i < 512*3; i++) fputc(0, psuFile); for(i = 0; i < ret; i++) { if(mcDir[i].AttrFile & MC_ATTR_SUBDIR) { dir.mode = 0x8427; memcpy(&dir.created, &mcDir[i]._Create, sizeof(sceMcStDateTime)); memcpy(&dir.modified, &mcDir[i]._Modify, sizeof(sceMcStDateTime)); } else if(mcDir[i].AttrFile & MC_ATTR_FILE) { progress += (float)1/(ret-2); drawCopyProgress(progress); file.mode = mcDir[i].AttrFile; file.length = mcDir[i].FileSizeByte; memcpy(&file.created, &mcDir[i]._Create, sizeof(sceMcStDateTime)); memcpy(&file.modified, &mcDir[i]._Modify, sizeof(sceMcStDateTime)); strncpy(file.name, mcDir[i].EntryName, 32); snprintf(filePath, 100, "%s/%s", save->path, file.name); mcFile = fopen(filePath, "rb"); data = malloc(file.length); fread(data, 1, file.length, mcFile); fclose(mcFile); fwrite(&file, 1, 512, psuFile); fwrite(data, 1, file.length, psuFile); free(data); numFiles++; padding = 1024 - (file.length % 1024); if(padding < 1024) { for(j = 0; j < padding; j++) fputc(0, psuFile); } } } fseek(psuFile, 0, SEEK_SET); dir.length = numFiles + 2; strncpy(dir.name, strstr(save->path, ":") + 1, 32); fwrite(&dir, 1, 512, psuFile); // root directory dir.length = 0; strncpy(dir.name, ".", 32); fwrite(&dir, 1, 512, psuFile); // . strncpy(dir.name, "..", 32); fwrite(&dir, 1, 512, psuFile); // .. fclose(psuFile); return 1; }
int createZIP(gameSave_t *save, device_t src) { FILE *mcFile; zipFile zf; zip_fileinfo zfi; sceMcTblGetDir mcDir[64] __attribute__((aligned(64))); fio_stat_t stat; char mcPath[100]; char zipPath[100]; char filePath[150]; char validName[32]; char *data; int i; int ret; float progress = 0.0; if(!save || !(src & (MC_SLOT_1|MC_SLOT_2))) return 0; replaceIllegalChars(save->name, validName, '-'); rtrim(validName); snprintf(zipPath, 100, "%s%s.zip", flashDriveDevice, validName); if(fioGetstat(zipPath, &stat) == 0) { const char *items[] = {"Yes", "No"}; int choice = displayPromptMenu(items, 2, "Save already exists. Do you want to overwrite it?"); if(choice == 1) return 0; } zf = zipOpen(zipPath, APPEND_STATUS_CREATE); if(!zf) return 0; snprintf(mcPath, 100, "%s/*", strstr(save->path, ":") + 1); mcGetDir((src == MC_SLOT_1) ? 0 : 1, 0, mcPath, 0, 54, mcDir); mcSync(0, NULL, &ret); for(i = 0; i < ret; i++) { if(mcDir[i].AttrFile & MC_ATTR_SUBDIR) continue; else if(mcDir[i].AttrFile & MC_ATTR_FILE) { progress += (float)1/(ret-2); drawCopyProgress(progress); snprintf(filePath, 100, "%s/%s", save->path, mcDir[i].EntryName); mcFile = fopen(filePath, "rb"); data = malloc(mcDir[i].FileSizeByte); fread(data, 1, mcDir[i].FileSizeByte, mcFile); fclose(mcFile); if(zipOpenNewFileInZip(zf, strstr(filePath, ":") + 1, &zfi, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_BEST_COMPRESSION) == ZIP_OK) { zipWriteInFileInZip(zf, data, mcDir[i].FileSizeByte); zipCloseFileInZip(zf); } else { zipClose(zf, NULL); free(data); return 0; } free(data); } } zipClose(zf, NULL); return 1; }
int main() { int fd, ret; int i; // Initialise SifInitRpc(0); LoadModules(); #ifdef TYPE_MC if(mcInit(MC_TYPE_MC) < 0) { printf("Failed to initialise memcard server!\n"); SleepThread(); } #else if(mcInit(MC_TYPE_XMC) < 0) { printf("Failed to initialise memcard server!\n"); SleepThread(); } #endif printf("\nMemory card library example code - by Sjeep\n\n"); // int mcGetInfo(int port, int slot, int* type, int* free, int* format); // // mcGetInfo retrieves memcard state info, such as the memcard type, free blocks and // the format status. // // mcGetInfo is passed pointers to three variables, which are filled upon completion // of the getinfo rpc command. The mcGetInfo return values are as follows: // // 0 : The same memory card has been connected since the last mcGetInfo call. // -1 : Switched to a formatted memory card. // -2 : Switched to an unformatted memory card. // -10 or less : The memory card could not be detected. // // NOTE: With the MCMAN/MCSERV, *format is always returned as 0 regardless of if // if the memcard is formatted or not. // Since this is the first call, -1 should be returned. mcGetInfo(0, 0, &mc_Type, &mc_Free, &mc_Format); mcSync(0, NULL, &ret); printf("mcGetInfo returned %d\n",ret); printf("Type: %d Free: %d Format: %d\n\n", mc_Type, mc_Free, mc_Format); // Assuming that the same memory card is connected, this should return 0 mcGetInfo(0,0,&mc_Type,&mc_Free,&mc_Format); mcSync(0, NULL, &ret); printf("mcGetInfo returned %d\n",ret); printf("Type: %d Free: %d Format: %d\n\n", mc_Type, mc_Free, mc_Format); // int mcGetDir(int port, int slot, char *name, unsigned mode, int maxent, mcTable* table); // // mcGetDir retrieves the directory structure of a specific path on the memory card. // // The filename is relative to the root of the memory card. Wildcards such as '*' and '?' // may be used. "maxent" is the maximum number of mcTable elements your array specified // by "table" can hold. The mc_getdir return values are as follows: // // 0 or more : The number of file entries that were obtained. // -2 : The memory card is unformatted // -4 : A non-existant path was specified in the "name" parameter // -10 or less : The memory card could not be detected. mcGetDir(0, 0, "/*", 0, ARRAY_ENTRIES - 10, mcDir); mcSync(0, NULL, &ret); printf("mcGetDir returned %d\n\nListing of root directory on memory card:\n\n", ret); for(i=0; i < ret; i++) { if(mcDir[i].attrFile & MC_ATTR_SUBDIR) printf("[DIR] %s\n", mcDir[i].name); else printf("%s - %d bytes\n", mcDir[i].name, mcDir[i].fileSizeByte); } // Check if existing save is present fd = fioOpen("mc0:PS2DEV/icon.sys", O_RDONLY); if(fd <= 0) { printf("\nNo previous save exists, creating...\n"); if((ret = CreateSave()) < 0) { printf("Failed to create save! Errorno: %d\n",ret); SleepThread(); } } else { printf("\nPrevious save exists, listing directory\n\n"); ret = mcGetDir(0, 0, "/PS2DEV/*", 0, ARRAY_ENTRIES, mcDir); printf("mcGetDir returned %d\n\n", ret); for(i=0; i < ret; i++) { if(mcDir[i].attrFile & MC_ATTR_SUBDIR) printf("[DIR] %s\n", mcDir[i].name); else printf("%s - %d bytes\n", mcDir[i].name, mcDir[i].fileSizeByte); } } // Return to the browser, so you can see the PS2Dev icon :) SifExitRpc(); return 0; }