Пример #1
0
        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);
        }
Пример #2
0
        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);
            }
        }
Пример #3
0
        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;
        }
Пример #4
0
 protected internal virtual string getCacheFileName(PbpSection section)
 {
     return(string.Format("{0}{1}{2}", CacheDirectory, System.IO.Path.DirectorySeparatorChar, section.umdFilename.Substring(9)));
 }