protected internal virtual int ioRead(PbpSection section, TPointer outputPointer, int offset, int Length) { if (filePointer < section.offset || filePointer >= section.offset + section.size) { return(0); } Length = System.Math.Min(Length, section.size - (int)(filePointer - section.offset)); if (Length > 0) { if (!section.availableInContents) { readSection(section); } outputPointer.setArray(offset, contents, (int)filePointer, Length); } return(Length); }
public XmbIsoVirtualFile(string umdFilename) : base(null) { this.umdFilename = umdFilename; umdName = System.IO.Path.GetFileName(umdFilename); File cacheDirectory = new File(CacheDirectory); bool createCacheFiles = !cacheDirectory.Directory; if (createCacheFiles) { cacheDirectory.mkdirs(); } try { UmdIsoReader iso = new UmdIsoReader(umdFilename); IVirtualFileSystem vfs = new UmdIsoVirtualFileSystem(iso); sections = new PbpSection[umdFilenames.Length + 1]; sections[0] = new PbpSection(); sections[0].index = 0; sections[0].offset = 0; sections[0].size = 0x28; sections[0].availableInContents = true; int offset = 0x28; SceIoStat stat = new SceIoStat(); for (int i = 0; i < umdFilenames.Length; i++) { PbpSection section = new PbpSection(); section.index = i + 1; section.offset = offset; section.umdFilename = umdFilenames[i]; if (vfs.ioGetstat(section.umdFilename, stat) >= 0) { section.size = (int)stat.size; if (log.TraceEnabled) { log.trace(string.Format("{0}: mapping {1} at offset 0x{2:X}, size 0x{3:X}", umdFilename, umdFilenames[i], section.offset, section.size)); } } string cacheFileName = getCacheFileName(section); File cacheFile = new File(cacheFileName); // Create only cache files for PARAM.SFO and ICON0.PNG if (createCacheFiles && i < 2) { IVirtualFile vFile = vfs.ioOpen(section.umdFilename, IoFileMgrForUser.PSP_O_RDONLY, 0); if (vFile != null) { section.size = (int)vFile.Length(); sbyte[] buffer = new sbyte[section.size]; int Length = vFile.ioRead(buffer, 0, buffer.Length); vFile.ioClose(); System.IO.Stream os = new System.IO.FileStream(cacheFile, System.IO.FileMode.Create, System.IO.FileAccess.Write); os.Write(buffer, 0, Length); os.Close(); } } if (cacheFile.canRead()) { section.cacheFile = cacheFile; } sections[section.index] = section; offset += section.size; } totalLength = offset; contents = new sbyte[offset]; ByteBuffer buffer = ByteBuffer.wrap(contents).order(ByteOrder.LITTLE_ENDIAN); buffer.putInt(PBP.PBP_MAGIC); buffer.putInt(0x10000); // version for (int i = 1; i < sections.Length; i++) { buffer.putInt(sections[i].offset); } int endSectionOffset = sections[sections.Length - 1].offset + sections[sections.Length - 1].size; for (int i = sections.Length; i <= 8; i++) { buffer.putInt(endSectionOffset); } if (log.TraceEnabled) { log.trace(string.Format("{0}: PBP header :{1}", umdFilename, Utilities.getMemoryDump(contents, sections[0].offset, sections[0].size))); } vfs.ioExit(); } catch (FileNotFoundException e) { Console.WriteLine("XmbIsoVirtualFile", e); } catch (IOException e) { Console.WriteLine("XmbIsoVirtualFile", e); } }
protected internal virtual void readSection(PbpSection section) { if (section.size > 0) { try { if (section.cacheFile != null) { //if (log.DebugEnabled) { Console.WriteLine(string.Format("XmbIsoVirtualFile.readSection from Cache {0}", section.cacheFile)); } System.IO.Stream @is = new System.IO.FileStream(section.cacheFile, System.IO.FileMode.Open, System.IO.FileAccess.Read); @is.Read(contents, section.offset, section.size); @is.Close(); } else { //if (log.DebugEnabled) { Console.WriteLine(string.Format("XmbIsoVirtualFile.readSection from UMD {0}", section.umdFilename)); } UmdIsoReader iso = new UmdIsoReader(umdFilename); IVirtualFileSystem vfs = new UmdIsoVirtualFileSystem(iso); IVirtualFile vFile = vfs.ioOpen(section.umdFilename, IoFileMgrForUser.PSP_O_RDONLY, 0); if (vFile != null) { vFile.ioRead(contents, section.offset, section.size); vFile.ioClose(); } vfs.ioExit(); } } catch (IOException e) { Console.WriteLine("readSection", e); } // PARAM.SFO? if (section.index == 1) { // Patch the CATEGORY in the PARAM.SFO: // the VSH is checking that the CATEGORY value is starting // with 'M' (meaning MemoryStick) and not 'U' (UMD). // Change the first letter 'U' into 'M'. int offset = section.offset; int keyTableOffset = readUnaligned32(contents, offset + 8) + offset; int valueTableOffset = readUnaligned32(contents, offset + 12) + offset; int numberKeys = readUnaligned32(contents, offset + 16); for (int i = 0; i < numberKeys; i++) { int keyOffset = readUnaligned16(contents, offset + 20 + i * 16); string key = Utilities.readStringZ(contents, keyTableOffset + keyOffset); if ("CATEGORY".Equals(key)) { int valueOffset = readUnaligned32(contents, offset + 20 + i * 16 + 12); char valueFirstChar = (char)contents[valueTableOffset + valueOffset]; // Change the first letter 'U' into 'M'. if (valueFirstChar == 'U') { contents[valueTableOffset + valueOffset] = (sbyte)'M'; } break; } } } } section.availableInContents = true; }
protected internal virtual string getCacheFileName(PbpSection section) { return(string.Format("{0}{1}{2}", CacheDirectory, System.IO.Path.DirectorySeparatorChar, section.umdFilename.Substring(9))); }