int SzExtractFile(int i, unsigned char *buffer) { // prepare some variables SzBlockIndex = 0xFFFFFFFF; SzOffset = 0; // Unzip the file SzRes = SzExtract2( &SzArchiveStream.InStream, &SzDb, i, // index of file &SzBlockIndex, // index of solid block &buffer, &SzBufferSize, &SzOffset, // offset of stream for required file in *outBuffer &SzOutSizeProcessed, // size of file in *outBuffer &SzAllocImp, &SzAllocTempImp); // close 7Zip archive and free memory SzClose(); // check for errors if(SzRes != SZ_OK) { // display error message SzDisplayError(SzRes); return 0; } else { return SzOutSizeProcessed; } }
int SzParse(char * filepath) { if(!filepath) return 0; int device; if(!FindDevice(browser.dir, &device) || !GetFileSize(browser.selIndex)) return 0; int nbfiles = 0; // save the length/offset of this file unsigned int filelen = browserList[browser.selIndex].length; // setup archive stream SzArchiveStream.offset = 0; SzArchiveStream.len = filelen; SzArchiveStream.pos = 0; // open file file = fopen (filepath, "rb"); if(!file) return 0; // set szMethod to current chosen load device szMethod = device; // set handler functions for reading data from SD/USB/SMB/DVD SzArchiveStream.InStream.Read = SzFileReadImp; SzArchiveStream.InStream.Seek = SzFileSeekImp; // set default 7Zip SDK handlers for allocation and freeing memory SzAllocImp.Alloc = SzAlloc; SzAllocImp.Free = SzFree; SzAllocTempImp.Alloc = SzAllocTemp; SzAllocTempImp.Free = SzFreeTemp; // prepare CRC and 7Zip database structures InitCrcTable(); SzArDbExInit(&SzDb); // open the archive SzRes = SzArchiveOpen(&SzArchiveStream.InStream, &SzDb, &SzAllocImp, &SzAllocTempImp); if (SzRes != SZ_OK) { SzDisplayError(SzRes); // free memory used by the 7z SDK SzClose(); } else // archive opened successfully { if(SzDb.Database.NumFiles > 0) { // Parses the 7z into a full file listing HaltParseThread(); // halt parsing ResetBrowser(); // reset browser // add '..' folder in case the user wants exit the 7z AddBrowserEntry(); sprintf(browserList[0].displayname, "Up One Level"); browserList[0].isdir = 1; browserList[0].length = filelen; browserList[0].icon = ICON_FOLDER; // get contents and parse them into file list structure unsigned int SzI, SzJ; SzJ = 1; for (SzI = 0; SzI < SzDb.Database.NumFiles; SzI++) { SzF = SzDb.Database.Files + SzI; // skip directories if (SzF->IsDirectory) continue; if(!AddBrowserEntry()) { ResetBrowser(); ErrorPrompt("Out of memory: too many files!"); SzClose(); SzJ = 0; break; } // parse information about this file to the file list structure snprintf(browserList[SzJ].filename, MAXJOLIET, "%s", SzF->Name); StripExt(browserList[SzJ].displayname, browserList[SzJ].filename); browserList[SzJ].length = SzF->Size; // filesize browserList[SzJ].isdir = 0; // only files will be displayed (-> no flags) browserList[SzJ].filenum = SzI; // the extraction function identifies the file with this number SzJ++; } nbfiles = SzJ; } else { SzClose(); } } CancelAction(); // close file fclose(file); return nbfiles; }
/**************************************************************************** * BrowserChangeFolder * * Update current directory and set new entry list if directory has changed ***************************************************************************/ int BrowserChangeFolder() { int device = 0; FindDevice(browser.dir, &device); if(inSz && browser.selIndex == 0) // inside a 7z, requesting to leave { inSz = false; SzClose(); } if(!UpdateDirName()) return -1; HaltParseThread(); CleanupPath(browser.dir); ResetBrowser(); if(browser.dir[0] != 0) { if(strstr(browser.dir, ".7z")) { BrowserLoadSz(); } else { ParseDirectory(true, true); } FindAndSelectLastLoadedFile(); } if(browser.numEntries == 0) { browser.dir[0] = 0; int i=0; #ifdef HW_RVL AddBrowserEntry(); sprintf(browserList[i].filename, "sd:/"); sprintf(browserList[i].displayname, "SD Card"); browserList[i].length = 0; browserList[i].isdir = 1; browserList[i].icon = ICON_SD; i++; AddBrowserEntry(); sprintf(browserList[i].filename, "usb:/"); sprintf(browserList[i].displayname, "USB Mass Storage"); browserList[i].length = 0; browserList[i].isdir = 1; browserList[i].icon = ICON_USB; i++; #else AddBrowserEntry(); sprintf(browserList[i].filename, "carda:/"); sprintf(browserList[i].displayname, "SD Gecko Slot A"); browserList[i].length = 0; browserList[i].isdir = 1; browserList[i].icon = ICON_SD; i++; AddBrowserEntry(); sprintf(browserList[i].filename, "cardb:/"); sprintf(browserList[i].displayname, "SD Gecko Slot B"); browserList[i].length = 0; browserList[i].isdir = 1; browserList[i].icon = ICON_SD; i++; #endif AddBrowserEntry(); sprintf(browserList[i].filename, "smb:/"); sprintf(browserList[i].displayname, "Network Share"); browserList[i].length = 0; browserList[i].isdir = 1; browserList[i].icon = ICON_SMB; i++; AddBrowserEntry(); sprintf(browserList[i].filename, "dvd:/"); sprintf(browserList[i].displayname, "Data DVD"); browserList[i].length = 0; browserList[i].isdir = 1; browserList[i].icon = ICON_DVD; i++; browser.numEntries += i; } if(browser.dir[0] == 0) { GCSettings.LoadFolder[0] = 0; GCSettings.LoadMethod = 0; } else { char * path = StripDevice(browser.dir); if(path != NULL) strcpy(GCSettings.LoadFolder, path); FindDevice(browser.dir, &GCSettings.LoadMethod); } return browser.numEntries; }
/**************************************************************************** * FileSelector * * Let user select a file from the listing ***************************************************************************/ int FileSelector (int method) { u32 p = 0; u32 wp = 0; u32 ph = 0; u32 wh = 0; signed char gc_ay = 0; signed char gc_sx = 0; signed char wm_ay = 0; signed char wm_sx = 0; int haverom = 0; int redraw = 1; int selectit = 0; int scroll_delay = 0; bool move_selection = 0; #define SCROLL_INITIAL_DELAY 15 #define SCROLL_LOOP_DELAY 2 while (haverom == 0) { if (redraw) ShowFiles (filelist, maxfiles, offset, selection); redraw = 0; VIDEO_WaitVSync(); // slow things down a bit so we don't overread the pads gc_ay = PAD_StickY (0); gc_sx = PAD_SubStickX (0); p = PAD_ButtonsDown (0); ph = PAD_ButtonsHeld (0); #ifdef HW_RVL wm_ay = WPAD_Stick (0, 0, 0); wm_sx = WPAD_Stick (0, 1, 1); wp = WPAD_ButtonsDown (0); wh = WPAD_ButtonsHeld (0); #endif /*** Check for exit combo ***/ if ( (gc_sx < -70) || (wm_sx < -70) || (wp & WPAD_BUTTON_HOME) || (wp & WPAD_CLASSIC_BUTTON_HOME) ) return 0; /*** Check buttons, perform actions ***/ if ( (p & PAD_BUTTON_A) || selectit || (wp & (WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A)) ) { if ( selectit ) selectit = 0; if (filelist[selection].flags) // This is directory { /* update current directory and set new entry list if directory has changed */ int status; if(inSz && selection == 0) // inside a 7z, requesting to leave { if(method == METHOD_DVD) { // go to directory the 7z was in dvddir = filelist[0].offset; dvddirlength = filelist[0].length; } inSz = false; status = 1; SzClose(); } else { status = UpdateDirName(method); } if (status == 1) // ok, open directory { switch (method) { case METHOD_SD: case METHOD_USB: maxfiles = ParseFATdirectory(method); break; case METHOD_DVD: maxfiles = ParseDVDdirectory(); break; case METHOD_SMB: maxfiles = ParseSMBdirectory(); break; } if (!maxfiles) { WaitPrompt ((char*) "Error reading directory !"); haverom = 1; // quit menu } } else if (status == -1) // directory name too long { haverom = 1; // quit menu } } else // this is a file { // 7z file - let's open it up to select a file inside if(IsSz()) { // we'll store the 7z filepath for extraction later if(!MakeROMPath(szpath, method)) { WaitPrompt((char*) "Maximum filepath length reached!"); return -1; } int szfiles = SzParse(szpath, method); if(szfiles) { maxfiles = szfiles; inSz = true; } else WaitPrompt((char*) "Error opening archive!"); } else { // store the filename (w/o ext) - used for sram/freeze naming StripExt(ROMFilename, filelist[selection].filename); ShowAction ((char *)"Loading..."); ROMLoaded = LoadVBAROM(method); inSz = false; if (ROMLoaded) { return 1; } else { WaitPrompt((char*) "Error loading ROM!"); } } } redraw = 1; } // End of A if ( (p & PAD_BUTTON_B) || (wp & (WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B)) ) { while ( (PAD_ButtonsDown(0) & PAD_BUTTON_B) #ifdef HW_RVL || (WPAD_ButtonsDown(0) & (WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B)) #endif ) VIDEO_WaitVSync(); if ( strcmp(filelist[0].filename,"..") == 0 ) { selection = 0; selectit = 1; } else if ( strcmp(filelist[1].filename,"..") == 0 ) { selection = selectit = 1; } else { return 0; } } // End of B if ( ((p | ph) & PAD_BUTTON_DOWN) || ((wp | wh) & (WPAD_BUTTON_DOWN | WPAD_CLASSIC_BUTTON_DOWN)) || (gc_ay < -PADCAL) || (wm_ay < -PADCAL) ) { if ( (p & PAD_BUTTON_DOWN) || (wp & (WPAD_BUTTON_DOWN | WPAD_CLASSIC_BUTTON_DOWN)) ) { /*** Button just pressed ***/ scroll_delay = SCROLL_INITIAL_DELAY; // reset scroll delay. move_selection = 1; //continue (move selection) } else if (scroll_delay == 0) { /*** Button is held ***/ scroll_delay = SCROLL_LOOP_DELAY; move_selection = 1; //continue (move selection) } else { scroll_delay--; // wait } if (move_selection) { selection++; if (selection == maxfiles) selection = offset = 0; if ((selection - offset) >= PAGESIZE) offset += PAGESIZE; redraw = 1; move_selection = 0; } } // End of down if ( ((p | ph) & PAD_BUTTON_UP) || ((wp | wh) & (WPAD_BUTTON_UP | WPAD_CLASSIC_BUTTON_UP)) || (gc_ay > PADCAL) || (wm_ay > PADCAL) ) { if ( (p & PAD_BUTTON_UP) || (wp & (WPAD_BUTTON_UP | WPAD_CLASSIC_BUTTON_UP)) ) { /*** Button just pressed***/ scroll_delay = SCROLL_INITIAL_DELAY; // reset scroll delay. move_selection = 1; //continue (move selection) } else if (scroll_delay == 0) { /*** Button is held ***/ scroll_delay = SCROLL_LOOP_DELAY; move_selection = 1; //continue (move selection) } else { scroll_delay--; // wait } if (move_selection) { selection--; if (selection < 0) { selection = maxfiles - 1; offset = selection - PAGESIZE + 1; } if (selection < offset) offset -= PAGESIZE; if (offset < 0) offset = 0; redraw = 1; move_selection = 0; } } // End of Up if ( (p & PAD_BUTTON_LEFT) || (wp & (WPAD_BUTTON_LEFT | WPAD_CLASSIC_BUTTON_LEFT)) ) { /*** Go back a page ***/ selection -= PAGESIZE; if (selection < 0) { selection = maxfiles - 1; offset = selection - PAGESIZE + 1; } if (selection < offset) offset -= PAGESIZE; if (offset < 0) offset = 0; redraw = 1; } if ( (p & PAD_BUTTON_RIGHT) || (wp & (WPAD_BUTTON_RIGHT | WPAD_CLASSIC_BUTTON_RIGHT)) ) { /*** Go forward a page ***/ selection += PAGESIZE; if (selection > maxfiles - 1) selection = offset = 0; if ((selection - offset) >= PAGESIZE) offset += PAGESIZE; redraw = 1; } } return 0; }
int SzParse(char * filepath, int method) { int nbfiles = 0; // save the offset and the length of this file inside the archive stream structure SzArchiveStream.offset = filelist[selection].offset; SzArchiveStream.len = filelist[selection].length; SzArchiveStream.pos = 0; // open file switch (method) { case METHOD_SD: case METHOD_USB: fatfile = fopen (filepath, "rb"); if(!fatfile) return 0; break; case METHOD_SMB: smbfile = OpenSMBFile(filepath); if(!smbfile) return 0; break; } // set szMethod to current chosen load method szMethod = method; // set handler functions for reading data from FAT/SMB/DVD SzArchiveStream.InStream.Read = SzFileReadImp; SzArchiveStream.InStream.Seek = SzFileSeekImp; // set default 7Zip SDK handlers for allocation and freeing memory SzAllocImp.Alloc = SzAlloc; SzAllocImp.Free = SzFree; SzAllocTempImp.Alloc = SzAllocTemp; SzAllocTempImp.Free = SzFreeTemp; // prepare CRC and 7Zip database structures InitCrcTable(); SzArDbExInit(&SzDb); // open the archive SzRes = SzArchiveOpen(&SzArchiveStream.InStream, &SzDb, &SzAllocImp, &SzAllocTempImp); if (SzRes != SZ_OK) { SzDisplayError(SzRes); // free memory used by the 7z SDK SzClose(); } else // archive opened successfully { if(SzDb.Database.NumFiles > 0) { // Parses the 7z into a full file listing // erase all previous entries memset(&filelist, 0, sizeof(FILEENTRIES) * MAXFILES); // add '..' folder in case the user wants exit the 7z strncpy(filelist[0].displayname, "..", 2); filelist[0].flags = 1; filelist[0].offset = dvddir; filelist[0].length = dvddirlength; // get contents and parse them into file list structure unsigned int SzI, SzJ; SzJ = 1; for (SzI = 0; SzI < SzDb.Database.NumFiles; SzI++) { SzF = SzDb.Database.Files + SzI; // skip directories if (SzF->IsDirectory) continue; // do not exceed MAXFILES to avoid possible buffer overflows if (SzJ == (MAXFILES - 1)) break; // parse information about this file to the dvd file list structure strncpy(filelist[SzJ].filename, SzF->Name, MAXJOLIET); // copy joliet name (useless...) filelist[SzJ].filename[MAXJOLIET] = 0; // terminate string strncpy(filelist[SzJ].displayname, SzF->Name, MAXDISPLAY+1); // crop name for display filelist[SzJ].length = SzF->Size; // filesize filelist[SzJ].offset = SzI; // the extraction function identifies the file with this number filelist[SzJ].flags = 0; // only files will be displayed (-> no flags) SzJ++; } // update maxfiles and select the first entry offset = selection = 0; nbfiles = SzJ; } else { SzArDbExFree(&SzDb, SzAllocImp.Free); } } // close file switch (method) { case METHOD_SD: case METHOD_USB: fclose(fatfile); break; case METHOD_SMB: SMB_CloseFile (smbfile); break; } return nbfiles; }
int SzParse(char * filepath, int method) { if(!filepath) return 0; int nbfiles = 0; // save the length/offset of this file unsigned int filelen = browserList[browser.selIndex].length; u64 fileoff = browserList[browser.selIndex].offset; // setup archive stream SzArchiveStream.offset = 0; SzArchiveStream.len = filelen; SzArchiveStream.pos = 0; // open file switch (method) { case METHOD_SD: case METHOD_USB: case METHOD_SMB: file = fopen (filepath, "rb"); if(!file) return 0; break; case METHOD_DVD: SwitchDVDFolder(filepath); break; } // set szMethod to current chosen load method szMethod = method; // set handler functions for reading data from SD/USB/SMB/DVD SzArchiveStream.InStream.Read = SzFileReadImp; SzArchiveStream.InStream.Seek = SzFileSeekImp; // set default 7Zip SDK handlers for allocation and freeing memory SzAllocImp.Alloc = SzAlloc; SzAllocImp.Free = SzFree; SzAllocTempImp.Alloc = SzAllocTemp; SzAllocTempImp.Free = SzFreeTemp; // prepare CRC and 7Zip database structures InitCrcTable(); SzArDbExInit(&SzDb); // open the archive SzRes = SzArchiveOpen(&SzArchiveStream.InStream, &SzDb, &SzAllocImp, &SzAllocTempImp); if (SzRes != SZ_OK) { SzDisplayError(SzRes); // free memory used by the 7z SDK SzClose(); } else // archive opened successfully { if(SzDb.Database.NumFiles > 0) { // Parses the 7z into a full file listing // reset browser ResetBrowser(); // add '..' folder in case the user wants exit the 7z strncpy(browserList[0].displayname, "..", 2); browserList[0].isdir = 1; browserList[0].offset = fileoff; browserList[0].length = filelen; // get contents and parse them into file list structure unsigned int SzI, SzJ; SzJ = 1; for (SzI = 0; SzI < SzDb.Database.NumFiles; SzI++) { SzF = SzDb.Database.Files + SzI; // skip directories if (SzF->IsDirectory) continue; BROWSERENTRY * newBrowserList = (BROWSERENTRY *)realloc(browserList, (SzJ+1) * sizeof(BROWSERENTRY)); if(!newBrowserList) // failed to allocate required memory { ResetBrowser(); WaitPrompt("Out of memory: too many files!"); nbfiles = 0; break; } else { browserList = newBrowserList; } memset(&(browserList[SzJ]), 0, sizeof(BROWSERENTRY)); // clear the new entry // parse information about this file to the dvd file list structure strncpy(browserList[SzJ].filename, SzF->Name, MAXJOLIET); // copy joliet name (useless...) strncpy(browserList[SzJ].displayname, SzF->Name, MAXDISPLAY); // crop name for display browserList[SzJ].length = SzF->Size; // filesize browserList[SzJ].offset = SzI; // the extraction function identifies the file with this number browserList[SzJ].isdir = 0; // only files will be displayed (-> no flags) SzJ++; } nbfiles = SzJ; } else { SzArDbExFree(&SzDb, SzAllocImp.Free); } } // close file switch (method) { case METHOD_SD: case METHOD_USB: case METHOD_SMB: fclose(file); break; } return nbfiles; }